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

LibWeb: Add and use the "snap a length as a border width" algorithm

Previously, we always rounded border-widths up when converting them to
device pixels. However, the spec asks us to follow a specific algorithm
to "snap" these values, so that the computed value is snapped.

The difference from before, is that widths of between 0 and 1 device
pixels are rounded up to 1, and and values larger than 1 are rounded
down.
This commit is contained in:
Sam Atkins 2023-07-30 16:15:38 +01:00 committed by Sam Atkins
parent 5ee1b7db7c
commit 6038e36250
3 changed files with 42 additions and 1 deletions

View file

@ -289,6 +289,28 @@ NodeWithStyle::NodeWithStyle(DOM::Document& document, DOM::Node* node, CSS::Comp
m_font = Platform::FontPlugin::the().default_font();
}
// https://www.w3.org/TR/css-values-4/#snap-a-length-as-a-border-width
static CSSPixels snap_a_length_as_a_border_width(double device_pixels_per_css_pixel, CSSPixels length)
{
// 1. Assert: len is non-negative.
VERIFY(length >= 0);
// 2. If len is an integer number of device pixels, do nothing.
auto device_pixels = length.to_double() * device_pixels_per_css_pixel;
if (device_pixels == trunc(device_pixels))
return length;
// 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 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 floor(device_pixels) / device_pixels_per_css_pixel;
return length;
}
void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
{
auto& computed_values = static_cast<CSS::MutableComputedValues&>(m_computed_values);
@ -676,7 +698,7 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
VERIFY_NOT_REACHED();
};
border.width = resolve_border_width();
border.width = snap_a_length_as_a_border_width(document().page()->client().device_pixels_per_css_pixel(), resolve_border_width());
}
};