1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 02:07:35 +00:00

LibWeb: Add CSSPixels::nearest_value_for(FloatingPoint)

This is intended to annotate conversions from unknown floating-point
values to CSSPixels, and make it more obvious the fp value will be
rounded to the nearest fixed-point value.
This commit is contained in:
MacDue 2023-08-26 15:57:31 +01:00 committed by Alexander Kalenik
parent 360c0eb509
commit 71baa8c31a
28 changed files with 120 additions and 112 deletions

View file

@ -1069,7 +1069,7 @@ void BlockFormattingContext::layout_list_item_marker(ListItemBox const& list_ite
marker_state.set_content_width(image_width + default_marker_width);
} else {
auto text_width = marker.font().width(marker.text());
marker_state.set_content_width(image_width + CSSPixels(text_width));
marker_state.set_content_width(image_width + CSSPixels::nearest_value_for(text_width));
}
marker_state.set_content_height(max(image_height, marker.font().pixel_size_rounded_up() + 1));
@ -1084,7 +1084,7 @@ void BlockFormattingContext::layout_list_item_marker(ListItemBox const& list_ite
list_item_state.set_content_width(list_item_state.content_width() - final_marker_width);
}
auto offset_y = max(CSSPixels(0), (CSSPixels(marker.line_height()) - marker_state.content_height()) / 2);
auto offset_y = max(CSSPixels(0), (marker.line_height() - marker_state.content_height()) / 2);
auto space_and_containing_margin = intrusion_by_floats_into_box(list_item_box, offset_y);
marker_state.set_content_offset({ space_and_containing_margin.left - final_marker_width, offset_y });

View file

@ -25,7 +25,7 @@ void ButtonBox::prepare_for_replaced_layout()
// value attribute. This is not the case with <button />, which contains
// its contents normally.
if (is<HTML::HTMLInputElement>(dom_node())) {
set_natural_width(CSSPixels(font().width(static_cast<HTML::HTMLInputElement&>(dom_node()).value())));
set_natural_width(CSSPixels::nearest_value_for(font().width(static_cast<HTML::HTMLInputElement&>(dom_node()).value())));
set_natural_height(font().pixel_size_rounded_up());
}
}

View file

@ -540,15 +540,15 @@ CSS::FlexBasis FlexFormattingContext::used_flex_basis_for_item(FlexItem const& i
CSSPixels FlexFormattingContext::calculate_main_size_from_cross_size_and_aspect_ratio(CSSPixels cross_size, double aspect_ratio) const
{
if (is_row_layout())
return CSSPixels(cross_size * aspect_ratio);
return CSSPixels(cross_size / aspect_ratio);
return CSSPixels::nearest_value_for(cross_size * aspect_ratio);
return CSSPixels::nearest_value_for(cross_size / aspect_ratio);
}
CSSPixels FlexFormattingContext::calculate_cross_size_from_main_size_and_aspect_ratio(CSSPixels main_size, double aspect_ratio) const
{
if (is_row_layout())
return CSSPixels(main_size / aspect_ratio);
return CSSPixels(main_size * aspect_ratio);
return CSSPixels::nearest_value_for(main_size / aspect_ratio);
return CSSPixels::nearest_value_for(main_size * aspect_ratio);
}
// This function takes a size in the main axis and adjusts it according to the aspect ratio of the box
@ -982,7 +982,7 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
// If the sum of the unfrozen flex items flex factors is less than one, multiply the initial free space by this sum.
if (auto sum_of_flex_factor_of_unfrozen_items = line.sum_of_flex_factor_of_unfrozen_items(); sum_of_flex_factor_of_unfrozen_items < 1 && initial_free_space.has_value()) {
auto value = CSSPixels(initial_free_space.value() * sum_of_flex_factor_of_unfrozen_items);
auto value = CSSPixels::nearest_value_for(initial_free_space.value() * sum_of_flex_factor_of_unfrozen_items);
// If the magnitude of this value is less than the magnitude of the remaining free space, use this as the remaining free space.
if (abs(value) < abs(line.remaining_free_space.value()))
line.remaining_free_space = value;
@ -1793,7 +1793,7 @@ CSSPixels FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container
product = flex_line.chosen_flex_fraction * static_cast<double>(item.box->computed_values().flex_grow());
else if (item.desired_flex_fraction < 0)
product = flex_line.chosen_flex_fraction * item.scaled_flex_shrink_factor;
auto result = item.flex_base_size + CSSPixels(product);
auto result = item.flex_base_size + CSSPixels::nearest_value_for(product);
auto const& computed_min_size = this->computed_main_min_size(item.box);
auto const& computed_max_size = this->computed_main_max_size(item.box);

View file

@ -500,7 +500,7 @@ CSSPixels FormattingContext::tentative_height_for_replaced_element(Box const& bo
//
// (used width) / (intrinsic ratio)
if (computed_height.is_auto() && box.has_preferred_aspect_ratio())
return CSSPixels(m_state.get(box).content_width() / static_cast<double>(box.preferred_aspect_ratio().value()));
return CSSPixels::nearest_value_for(m_state.get(box).content_width() / static_cast<double>(box.preferred_aspect_ratio().value()));
// Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'.
if (computed_height.is_auto() && box.has_natural_height())
@ -1403,7 +1403,7 @@ CSSPixels FormattingContext::calculate_min_content_height(Layout::Box const& box
CSSPixels FormattingContext::calculate_max_content_height(Layout::Box const& box, CSSPixels width) const
{
if (box.has_preferred_aspect_ratio())
return CSSPixels(width / static_cast<double>(*box.preferred_aspect_ratio()));
return CSSPixels::nearest_value_for(width / static_cast<double>(*box.preferred_aspect_ratio()));
if (box.has_natural_height())
return *box.natural_height();
@ -1711,10 +1711,10 @@ CSSPixels FormattingContext::box_baseline(Box const& box) const
return box_state.content_height() + box_state.margin_box_top();
case CSS::VerticalAlign::TextTop:
// TextTop: Align the top of the box with the top of the parent's content area (see 10.6.1).
return CSSPixels(box.computed_values().font_size());
return CSSPixels::nearest_value_for(box.computed_values().font_size());
case CSS::VerticalAlign::TextBottom:
// TextTop: Align the bottom of the box with the bottom of the parent's content area (see 10.6.1).
return box_state.content_height() - CSSPixels(box.containing_block()->font().pixel_metrics().descent * 2);
return box_state.content_height() - CSSPixels::nearest_value_for(box.containing_block()->font().pixel_metrics().descent * 2);
default:
break;
}

View file

@ -1245,7 +1245,7 @@ void GridFormattingContext::expand_flexible_tracks(AvailableSpace const& availab
for (auto& track : tracks) {
if (track.max_track_sizing_function.is_flexible_length()) {
if (track.max_track_sizing_function.flex_factor() > 1) {
result = max(result, CSSPixels(track.base_size / track.max_track_sizing_function.flex_factor()));
result = max(result, CSSPixels::nearest_value_for(track.base_size / track.max_track_sizing_function.flex_factor()));
} else {
result = max(result, track.base_size);
}

View file

@ -34,11 +34,11 @@ void ImageBox::prepare_for_replaced_layout()
CSSPixels alt_text_width = 0;
if (!m_cached_alt_text_width.has_value())
m_cached_alt_text_width = CSSPixels(font.width(alt));
m_cached_alt_text_width = CSSPixels::nearest_value_for(font.width(alt));
alt_text_width = m_cached_alt_text_width.value();
set_natural_width(alt_text_width + 16);
set_natural_height(CSSPixels(font.pixel_size()) + 16);
set_natural_height(CSSPixels::nearest_value_for(font.pixel_size()) + 16);
}
if (!has_natural_width() && !has_natural_height()) {

View file

@ -180,7 +180,7 @@ Optional<InlineLevelIterator::Item> InlineLevelIterator::next_without_lookahead(
m_text_node_context->is_last_chunk = true;
auto& chunk = chunk_opt.value();
CSSPixels chunk_width = CSSPixels(text_node.font().width(chunk.view) + text_node.font().glyph_spacing());
CSSPixels chunk_width = CSSPixels::nearest_value_for(text_node.font().width(chunk.view) + text_node.font().glyph_spacing());
if (m_text_node_context->do_respect_linebreaks && chunk.has_breaking_newline) {
return Item {

View file

@ -51,7 +51,7 @@ int LineBoxFragment::text_index_at(CSSPixels x) const
Utf8View view(text());
CSSPixels relative_x = x - absolute_x();
CSSPixels glyph_spacing = CSSPixels(font.glyph_spacing());
CSSPixels glyph_spacing = font.glyph_spacing();
if (relative_x < 0)
return 0;
@ -59,7 +59,7 @@ int LineBoxFragment::text_index_at(CSSPixels x) const
CSSPixels width_so_far = 0;
for (auto it = view.begin(); it != view.end(); ++it) {
auto previous_it = it;
CSSPixels glyph_width = CSSPixels(font.glyph_or_emoji_width(it));
CSSPixels glyph_width = CSSPixels::nearest_value_for(font.glyph_or_emoji_width(it));
if ((width_so_far + glyph_width + glyph_spacing / 2) > relative_x)
return m_start + view.byte_offset_of(previous_it);
@ -105,8 +105,8 @@ CSSPixelRect LineBoxFragment::selection_rect(Gfx::Font const& font) const
auto selection_start_in_this_fragment = max(0, range->start_offset() - m_start);
auto selection_end_in_this_fragment = min(m_length, range->end_offset() - m_start);
auto pixel_distance_to_first_selected_character = CSSPixels(font.width(text.substring_view(0, selection_start_in_this_fragment)));
auto pixel_width_of_selection = CSSPixels(font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment))) + 1;
auto pixel_distance_to_first_selected_character = CSSPixels::nearest_value_for(font.width(text.substring_view(0, selection_start_in_this_fragment)));
auto pixel_width_of_selection = CSSPixels::nearest_value_for(font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment))) + 1;
auto rect = absolute_rect();
rect.set_x(rect.x() + pixel_distance_to_first_selected_character);
@ -121,8 +121,8 @@ CSSPixelRect LineBoxFragment::selection_rect(Gfx::Font const& font) const
auto selection_start_in_this_fragment = max(0, range->start_offset() - m_start);
auto selection_end_in_this_fragment = m_length;
auto pixel_distance_to_first_selected_character = CSSPixels(font.width(text.substring_view(0, selection_start_in_this_fragment)));
auto pixel_width_of_selection = CSSPixels(font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment))) + 1;
auto pixel_distance_to_first_selected_character = CSSPixels::nearest_value_for(font.width(text.substring_view(0, selection_start_in_this_fragment)));
auto pixel_width_of_selection = CSSPixels::nearest_value_for(font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment))) + 1;
auto rect = absolute_rect();
rect.set_x(rect.x() + pixel_distance_to_first_selected_character);
@ -137,8 +137,8 @@ CSSPixelRect LineBoxFragment::selection_rect(Gfx::Font const& font) const
auto selection_start_in_this_fragment = 0;
auto selection_end_in_this_fragment = min(range->end_offset() - m_start, m_length);
auto pixel_distance_to_first_selected_character = CSSPixels(font.width(text.substring_view(0, selection_start_in_this_fragment)));
auto pixel_width_of_selection = CSSPixels(font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment))) + 1;
auto pixel_distance_to_first_selected_character = CSSPixels::nearest_value_for(font.width(text.substring_view(0, selection_start_in_this_fragment)));
auto pixel_width_of_selection = CSSPixels::nearest_value_for(font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment))) + 1;
auto rect = absolute_rect();
rect.set_x(rect.x() + pixel_distance_to_first_selected_character);

View file

@ -195,10 +195,10 @@ void LineBuilder::update_last_line()
auto& font = m_context.containing_block().font();
auto const line_height = m_context.containing_block().line_height();
auto const font_metrics = font.pixel_metrics();
auto const typographic_height = CSSPixels(font_metrics.ascent + font_metrics.descent);
auto const typographic_height = CSSPixels::nearest_value_for(font_metrics.ascent + font_metrics.descent);
auto const leading = line_height - typographic_height;
auto const half_leading = leading / 2;
return CSSPixels(font_metrics.ascent) + half_leading;
return CSSPixels::nearest_value_for(font_metrics.ascent) + half_leading;
}();
auto line_box_baseline = [&] {
@ -207,7 +207,7 @@ void LineBuilder::update_last_line()
auto const& font = fragment.layout_node().font();
auto const line_height = fragment.layout_node().line_height();
auto const font_metrics = font.pixel_metrics();
auto const typographic_height = CSSPixels(font_metrics.ascent + font_metrics.descent);
auto const typographic_height = CSSPixels::nearest_value_for(font_metrics.ascent + font_metrics.descent);
auto const leading = line_height - typographic_height;
auto const half_leading = leading / 2;
@ -215,7 +215,7 @@ void LineBuilder::update_last_line()
CSSPixels fragment_baseline = 0;
if (fragment.layout_node().is_text_node()) {
fragment_baseline = CSSPixels(font_metrics.ascent) + half_leading;
fragment_baseline = CSSPixels::nearest_value_for(font_metrics.ascent) + half_leading;
} else {
auto const& box = verify_cast<Layout::Box>(fragment.layout_node());
fragment_baseline = m_context.box_baseline(box);
@ -302,11 +302,11 @@ void LineBuilder::update_last_line()
bottom_of_inline_box = (fragment.offset().y() + fragment_box_state.content_height() + fragment_box_state.margin_box_bottom());
} else {
auto font_metrics = fragment.layout_node().font().pixel_metrics();
auto typographic_height = CSSPixels(font_metrics.ascent + font_metrics.descent);
auto typographic_height = CSSPixels::nearest_value_for(font_metrics.ascent + font_metrics.descent);
auto leading = fragment.layout_node().line_height() - typographic_height;
auto half_leading = leading / 2;
top_of_inline_box = (fragment.offset().y() + fragment.baseline() - CSSPixels(font_metrics.ascent) - half_leading);
bottom_of_inline_box = (fragment.offset().y() + fragment.baseline() + CSSPixels(font_metrics.descent) + half_leading);
top_of_inline_box = (fragment.offset().y() + fragment.baseline() - CSSPixels::nearest_value_for(font_metrics.ascent) - half_leading);
bottom_of_inline_box = (fragment.offset().y() + fragment.baseline() + CSSPixels::nearest_value_for(font_metrics.descent) + half_leading);
}
if (auto const* length_percentage = fragment.layout_node().computed_values().vertical_align().get_pointer<CSS::LengthPercentage>()) {
if (length_percentage->is_length())

View file

@ -300,11 +300,11 @@ static CSSPixels snap_a_length_as_a_border_width(double device_pixels_per_css_pi
// 3. If len is greater than zero, but less than 1 device pixel, round len up to 1 device pixel.
if (device_pixels > 0 && device_pixels < 1)
return CSSPixels(1 / device_pixels_per_css_pixel);
return CSSPixels::nearest_value_for(1 / device_pixels_per_css_pixel);
// 4. If len is greater than 1 device pixel, round it down to the nearest integer number of device pixels.
if (device_pixels > 1)
return CSSPixels(floor(device_pixels) / device_pixels_per_css_pixel);
return CSSPixels::nearest_value_for(floor(device_pixels) / device_pixels_per_css_pixel);
return length;
}
@ -742,7 +742,7 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
// FIXME: Converting to pixels isn't really correct - values should be in "user units"
// https://svgwg.org/svg2-draft/coords.html#TermUserUnits
if (stroke_width->is_number())
computed_values.set_stroke_width(CSS::Length::make_px(CSSPixels(stroke_width->as_number().number())));
computed_values.set_stroke_width(CSS::Length::make_px(CSSPixels::nearest_value_for(stroke_width->as_number().number())));
else if (stroke_width->is_length())
computed_values.set_stroke_width(stroke_width->as_length().length());
else if (stroke_width->is_percentage())

View file

@ -86,13 +86,13 @@ static ViewBoxTransform scale_and_align_viewbox_content(SVG::PreserveAspectRatio
case SVG::PreserveAspectRatio::Align::xMidYMid:
case SVG::PreserveAspectRatio::Align::xMidYMax:
// Align the midpoint X value of the element's viewBox with the midpoint X value of the SVG viewport.
viewbox_transform.offset.translate_by((svg_box_state.content_width() - CSSPixels(view_box.width * viewbox_transform.scale_factor)) / 2, 0);
viewbox_transform.offset.translate_by((svg_box_state.content_width() - CSSPixels::nearest_value_for(view_box.width * viewbox_transform.scale_factor)) / 2, 0);
break;
case SVG::PreserveAspectRatio::Align::xMaxYMin:
case SVG::PreserveAspectRatio::Align::xMaxYMid:
case SVG::PreserveAspectRatio::Align::xMaxYMax:
// Align the <min-x>+<width> of the element's viewBox with the maximum X value of the SVG viewport.
viewbox_transform.offset.translate_by((svg_box_state.content_width() - CSSPixels(view_box.width * viewbox_transform.scale_factor)), 0);
viewbox_transform.offset.translate_by((svg_box_state.content_width() - CSSPixels::nearest_value_for(view_box.width * viewbox_transform.scale_factor)), 0);
break;
default:
VERIFY_NOT_REACHED();
@ -117,13 +117,13 @@ static ViewBoxTransform scale_and_align_viewbox_content(SVG::PreserveAspectRatio
case SVG::PreserveAspectRatio::Align::xMidYMid:
case SVG::PreserveAspectRatio::Align::xMaxYMid:
// Align the midpoint Y value of the element's viewBox with the midpoint Y value of the SVG viewport.
viewbox_transform.offset.translate_by(0, (svg_box_state.content_height() - CSSPixels(view_box.height * viewbox_transform.scale_factor)) / 2);
viewbox_transform.offset.translate_by(0, (svg_box_state.content_height() - CSSPixels::nearest_value_for(view_box.height * viewbox_transform.scale_factor)) / 2);
break;
case SVG::PreserveAspectRatio::Align::xMinYMax:
case SVG::PreserveAspectRatio::Align::xMidYMax:
case SVG::PreserveAspectRatio::Align::xMaxYMax:
// Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the SVG viewport.
viewbox_transform.offset.translate_by(0, (svg_box_state.content_height() - CSSPixels(view_box.height * viewbox_transform.scale_factor)));
viewbox_transform.offset.translate_by(0, (svg_box_state.content_height() - CSSPixels::nearest_value_for(view_box.height * viewbox_transform.scale_factor)));
break;
default:
VERIFY_NOT_REACHED();
@ -197,7 +197,7 @@ void SVGFormattingContext::run(Box const& box, LayoutMode layout_mode, Available
// Stroke increases the path's size by stroke_width/2 per side.
auto path_bounding_box = path_transform.map(path.bounding_box()).to_type<CSSPixels>();
CSSPixels stroke_width = CSSPixels(static_cast<double>(geometry_box.dom_node().visible_stroke_width()) * viewbox_scale);
CSSPixels stroke_width = CSSPixels::nearest_value_for(static_cast<double>(geometry_box.dom_node().visible_stroke_width()) * viewbox_scale);
path_bounding_box.inflate(stroke_width, stroke_width);
geometry_box_state.set_content_offset(path_bounding_box.top_left());
geometry_box_state.set_content_width(path_bounding_box.width());

View file

@ -265,11 +265,11 @@ void TableFormattingContext::compute_intrinsic_percentage(size_t max_cell_span)
auto cell_start_rc_index = cell_index<RowOrColumn>(cell);
auto cell_end_rc_index = cell_start_rc_index + cell_span_value;
// 1. Start with the percentage contribution of the cell.
CSSPixels cell_contribution = CSSPixels(cell_percentage_contribution<RowOrColumn>(cell));
CSSPixels cell_contribution = CSSPixels::nearest_value_for(cell_percentage_contribution<RowOrColumn>(cell));
// 2. Subtract the intrinsic percentage width of the column based on cells of span up to N-1 of all columns
// that the cell spans. If this gives a negative result, change it to 0%.
for (auto rc_index = cell_start_rc_index; rc_index < cell_end_rc_index; rc_index++) {
cell_contribution -= CSSPixels(rows_or_columns[rc_index].intrinsic_percentage);
cell_contribution -= CSSPixels::nearest_value_for(rows_or_columns[rc_index].intrinsic_percentage);
cell_contribution = max(cell_contribution, 0);
}
// Compute the sum of the non-spanning max-content sizes of all rows / columns spanned by the cell that have an intrinsic percentage
@ -380,12 +380,12 @@ void TableFormattingContext::compute_table_measures()
auto clamped_diff_to_baseline_min = min(
max(cell_min_size<RowOrColumn>(cell) - baseline_min_content_size - baseline_border_spacing, 0),
baseline_max_content_size - baseline_min_content_size);
cell_min_contribution += CSSPixels(normalized_max_min_diff * clamped_diff_to_baseline_min);
cell_min_contribution += CSSPixels::nearest_value_for(normalized_max_min_diff * clamped_diff_to_baseline_min);
// the product of:
// - the ratio of the max-content size based on cells of span up to N-1 of the column to the baseline max-content size
// - the outer min-content size of the cell minus the baseline max-content size and baseline border spacing, or 0 if this is negative
if (baseline_max_content_size != 0) {
cell_min_contribution += CSSPixels(rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
cell_min_contribution += CSSPixels::nearest_value_for(rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
* max(CSSPixels(0), cell_min_size<RowOrColumn>(cell) - baseline_max_content_size - baseline_border_spacing);
}
@ -396,7 +396,7 @@ void TableFormattingContext::compute_table_measures()
// - the ratio of the max-content size based on cells of span up to N-1 of the column to the baseline max-content size
// - the outer max-content size of the cell minus the baseline max-content size and the baseline border spacing, or 0 if this is negative
if (baseline_max_content_size != 0) {
cell_max_contribution += CSSPixels(rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
cell_max_contribution += CSSPixels::nearest_value_for(rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
* max(CSSPixels(0), cell_max_size<RowOrColumn>(cell) - baseline_max_content_size - baseline_border_spacing);
}
cell_min_contributions_by_rc_index[rc_index].append(cell_min_contribution);
@ -496,7 +496,7 @@ void TableFormattingContext::compute_table_width()
for (auto& cell : m_cells) {
auto const& cell_width = cell.box->computed_values().width();
if (cell_width.is_percentage()) {
adjusted_used_width = CSSPixels(ceil(100 / cell_width.percentage().value() * cell.outer_max_width.to_double()));
adjusted_used_width = CSSPixels::nearest_value_for(ceil(100 / cell_width.percentage().value() * cell.outer_max_width.to_double()));
if (width_of_table_containing_block.is_definite())
used_width = min(max(used_width, adjusted_used_width), width_of_table_containing_block.to_px_or_zero());
else
@ -555,7 +555,7 @@ void TableFormattingContext::assign_columns_width_linear_combination(Vector<CSSP
auto candidate_weight = (available_width - columns_total_used_width) / static_cast<double>(columns_total_candidate_width - columns_total_used_width);
for (size_t i = 0; i < m_columns.size(); ++i) {
auto& column = m_columns[i];
column.used_width = CSSPixels(candidate_weight * candidate_widths[i] + (1 - candidate_weight) * column.used_width);
column.used_width = CSSPixels::nearest_value_for(candidate_weight * candidate_widths[i] + (1 - candidate_weight) * column.used_width);
}
}
@ -576,7 +576,7 @@ bool TableFormattingContext::distribute_excess_width_proportionally_to_base_widt
VERIFY(total_base_width > 0);
for (auto& column : m_columns) {
if (column_filter(column)) {
column.used_width += CSSPixels(excess_width * base_width_getter(column) / static_cast<double>(total_base_width));
column.used_width += CSSPixels::nearest_value_for(excess_width * base_width_getter(column) / static_cast<double>(total_base_width));
}
}
return true;
@ -618,7 +618,7 @@ bool TableFormattingContext::distribute_excess_width_by_intrinsic_percentage(CSS
}
for (auto& column : m_columns) {
if (column_filter(column)) {
column.used_width += CSSPixels(excess_width * column.intrinsic_percentage / total_percentage_width);
column.used_width += CSSPixels::nearest_value_for(excess_width * column.intrinsic_percentage / total_percentage_width);
}
}
return true;
@ -660,7 +660,7 @@ void TableFormattingContext::distribute_width_to_columns()
for (size_t i = 0; i < m_columns.size(); ++i) {
auto& column = m_columns[i];
if (column.has_intrinsic_percentage) {
candidate_widths[i] = max(column.min_size, CSSPixels(column.intrinsic_percentage / 100 * available_width));
candidate_widths[i] = max(column.min_size, CSSPixels::nearest_value_for(column.intrinsic_percentage / 100 * available_width));
}
}
@ -990,7 +990,7 @@ void TableFormattingContext::distribute_height_to_rows()
for (auto& row : m_rows) {
auto weight = row.reference_height / static_cast<double>(sum_reference_height);
auto final_height = m_table_height * weight;
row.final_height = CSSPixels(final_height);
row.final_height = CSSPixels::nearest_value_for(final_height);
}
} else if (rows_with_auto_height.size() > 0) {
// Else, if the table owns any “auto-height” row (a row whose size is only determined by its content size and