.container) [10,10 802x19.46875]
- PaintableWithLines (BlockContainer(anonymous)) [392.21875,11 37.578125x17.46875]
+ PaintableWithLines (BlockContainer(anonymous)) [392.203125,11 37.578125x17.46875]
TextPaintable (TextNode<#text>)
diff --git a/Tests/LibWeb/TestCSSPixels.cpp b/Tests/LibWeb/TestCSSPixels.cpp
index 66b7059466..4851c29843 100644
--- a/Tests/LibWeb/TestCSSPixels.cpp
+++ b/Tests/LibWeb/TestCSSPixels.cpp
@@ -33,7 +33,7 @@ TEST_CASE(division1)
EXPECT_EQ(c, CSSPixels(2));
a = CSSPixels::from_raw(0x3FFF'FFFF); // int_max / 2
- b = 0.25;
+ b = CSSPixels(0.25);
EXPECT(!a.might_be_saturated());
EXPECT((a / b).might_be_saturated());
}
diff --git a/Tests/LibWeb/Text/expected/hit_testing/text.txt b/Tests/LibWeb/Text/expected/hit_testing/text.txt
index be483b517a..c685607e73 100644
--- a/Tests/LibWeb/Text/expected/hit_testing/text.txt
+++ b/Tests/LibWeb/Text/expected/hit_testing/text.txt
@@ -1 +1 @@
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eu ante est. Integer ipsum sem, tincidunt quis felis quis, efficitur fringilla neque. Aliquam erat volutpat. Donec feugiat euismod sapien. Donec vel egestas arcu. Suspendisse luctus rhoncus mi quis elementum. Maecenas vel nisi maximus, viverra tellus quis, ultrices elit. Quisque congue velit quis lectus congue, ut consectetur nulla pharetra. Nullam euismod leo eget magna auctor, et bibendum urna tincidunt. Morbi molestie gravida ex ac consectetur. Duis pretium gravida augue eu sagittis. 193
\ No newline at end of file
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eu ante est. Integer ipsum sem, tincidunt quis felis quis, efficitur fringilla neque. Aliquam erat volutpat. Donec feugiat euismod sapien. Donec vel egestas arcu. Suspendisse luctus rhoncus mi quis elementum. Maecenas vel nisi maximus, viverra tellus quis, ultrices elit. Quisque congue velit quis lectus congue, ut consectetur nulla pharetra. Nullam euismod leo eget magna auctor, et bibendum urna tincidunt. Morbi molestie gravida ex ac consectetur. Duis pretium gravida augue eu sagittis. 192
diff --git a/Userland/Applications/Browser/InspectorWidget.cpp b/Userland/Applications/Browser/InspectorWidget.cpp
index c7d4f5ef6a..71d3b29092 100644
--- a/Userland/Applications/Browser/InspectorWidget.cpp
+++ b/Userland/Applications/Browser/InspectorWidget.cpp
@@ -185,18 +185,18 @@ void InspectorWidget::update_node_box_model(StringView node_box_sizing_json)
auto json_value = json_or_error.release_value();
auto const& json_object = json_value.as_object();
- m_node_box_sizing.margin.top = json_object.get_float("margin_top"sv).value_or(0);
- m_node_box_sizing.margin.right = json_object.get_float("margin_right"sv).value_or(0);
- m_node_box_sizing.margin.bottom = json_object.get_float("margin_bottom"sv).value_or(0);
- m_node_box_sizing.margin.left = json_object.get_float("margin_left"sv).value_or(0);
- m_node_box_sizing.padding.top = json_object.get_float("padding_top"sv).value_or(0);
- m_node_box_sizing.padding.right = json_object.get_float("padding_right"sv).value_or(0);
- m_node_box_sizing.padding.bottom = json_object.get_float("padding_bottom"sv).value_or(0);
- m_node_box_sizing.padding.left = json_object.get_float("padding_left"sv).value_or(0);
- m_node_box_sizing.border.top = json_object.get_float("border_top"sv).value_or(0);
- m_node_box_sizing.border.right = json_object.get_float("border_right"sv).value_or(0);
- m_node_box_sizing.border.bottom = json_object.get_float("border_bottom"sv).value_or(0);
- m_node_box_sizing.border.left = json_object.get_float("border_left"sv).value_or(0);
+ m_node_box_sizing.margin.top = Web::CSSPixels(json_object.get_float("margin_top"sv).value_or(0));
+ m_node_box_sizing.margin.right = Web::CSSPixels(json_object.get_float("margin_right"sv).value_or(0));
+ m_node_box_sizing.margin.bottom = Web::CSSPixels(json_object.get_float("margin_bottom"sv).value_or(0));
+ m_node_box_sizing.margin.left = Web::CSSPixels(json_object.get_float("margin_left"sv).value_or(0));
+ m_node_box_sizing.padding.top = Web::CSSPixels(json_object.get_float("padding_top"sv).value_or(0));
+ m_node_box_sizing.padding.right = Web::CSSPixels(json_object.get_float("padding_right"sv).value_or(0));
+ m_node_box_sizing.padding.bottom = Web::CSSPixels(json_object.get_float("padding_bottom"sv).value_or(0));
+ m_node_box_sizing.padding.left = Web::CSSPixels(json_object.get_float("padding_left"sv).value_or(0));
+ m_node_box_sizing.border.top = Web::CSSPixels(json_object.get_float("border_top"sv).value_or(0));
+ m_node_box_sizing.border.right = Web::CSSPixels(json_object.get_float("border_right"sv).value_or(0));
+ m_node_box_sizing.border.bottom = Web::CSSPixels(json_object.get_float("border_bottom"sv).value_or(0));
+ m_node_box_sizing.border.left = Web::CSSPixels(json_object.get_float("border_left"sv).value_or(0));
m_element_size_view->set_node_content_width(json_object.get_float("content_width"sv).value_or(0));
m_element_size_view->set_node_content_height(json_object.get_float("content_height"sv).value_or(0));
diff --git a/Userland/Libraries/LibWeb/CSS/EdgeRect.cpp b/Userland/Libraries/LibWeb/CSS/EdgeRect.cpp
index eb71dba606..c432ef5c9d 100644
--- a/Userland/Libraries/LibWeb/CSS/EdgeRect.cpp
+++ b/Userland/Libraries/LibWeb/CSS/EdgeRect.cpp
@@ -24,10 +24,10 @@ Gfx::FloatRect EdgeRect::resolved(Layout::Node const& layout_node, Gfx::Rect
, and the same as the used value of the width plus the sum of the
// horizontal padding and border widths for , such that four 'auto' values result in the
// clipping region being the same as the element's border box).
- auto left = border_box.left() + (left_edge.is_auto() ? 0 : left_edge.to_px(layout_node)).to_double();
- auto top = border_box.top() + (top_edge.is_auto() ? 0 : top_edge.to_px(layout_node)).to_double();
- auto right = border_box.left() + (right_edge.is_auto() ? border_box.width() : right_edge.to_px(layout_node)).to_double();
- auto bottom = border_box.top() + (bottom_edge.is_auto() ? border_box.height() : bottom_edge.to_px(layout_node)).to_double();
+ auto left = border_box.left() + (left_edge.is_auto() ? 0 : left_edge.to_px(layout_node).to_double());
+ auto top = border_box.top() + (top_edge.is_auto() ? 0 : top_edge.to_px(layout_node).to_double());
+ auto right = border_box.left() + (right_edge.is_auto() ? border_box.width() : right_edge.to_px(layout_node).to_double());
+ auto bottom = border_box.top() + (bottom_edge.is_auto() ? border_box.height() : bottom_edge.to_px(layout_node).to_double());
return Gfx::FloatRect {
left,
top,
diff --git a/Userland/Libraries/LibWeb/CSS/Length.cpp b/Userland/Libraries/LibWeb/CSS/Length.cpp
index b398e5784c..88c670a841 100644
--- a/Userland/Libraries/LibWeb/CSS/Length.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Length.cpp
@@ -61,31 +61,31 @@ CSSPixels Length::font_relative_length_to_px(Length::FontMetrics const& font_met
{
switch (m_type) {
case Type::Em:
- return m_value * font_metrics.font_size.to_double();
+ return CSSPixels(m_value * font_metrics.font_size.to_double());
case Type::Rem:
- return m_value * root_font_metrics.font_size.to_double();
+ return CSSPixels(m_value * root_font_metrics.font_size.to_double());
case Type::Ex:
- return m_value * font_metrics.x_height.to_double();
+ return CSSPixels(m_value * font_metrics.x_height.to_double());
case Type::Rex:
- return m_value * root_font_metrics.x_height.to_double();
+ return CSSPixels(m_value * root_font_metrics.x_height.to_double());
case Type::Cap:
- return m_value * font_metrics.cap_height.to_double();
+ return CSSPixels(m_value * font_metrics.cap_height.to_double());
case Type::Rcap:
- return m_value * root_font_metrics.cap_height.to_double();
+ return CSSPixels(m_value * root_font_metrics.cap_height.to_double());
case Type::Ch:
- return m_value * font_metrics.zero_advance.to_double();
+ return CSSPixels(m_value * font_metrics.zero_advance.to_double());
case Type::Rch:
- return m_value * root_font_metrics.zero_advance.to_double();
+ return CSSPixels(m_value * root_font_metrics.zero_advance.to_double());
case Type::Ic:
// FIXME: Use the "advance measure of the “水” (CJK water ideograph, U+6C34) glyph"
- return m_value * font_metrics.font_size.to_double();
+ return CSSPixels(m_value * font_metrics.font_size.to_double());
case Type::Ric:
// FIXME: Use the "advance measure of the “水” (CJK water ideograph, U+6C34) glyph"
- return m_value * root_font_metrics.font_size.to_double();
+ return CSSPixels(m_value * root_font_metrics.font_size.to_double());
case Type::Lh:
- return m_value * font_metrics.line_height.to_double();
+ return CSSPixels(m_value * font_metrics.line_height.to_double());
case Type::Rlh:
- return m_value * root_font_metrics.line_height.to_double();
+ return CSSPixels(m_value * root_font_metrics.line_height.to_double());
default:
VERIFY_NOT_REACHED();
}
@@ -98,34 +98,34 @@ CSSPixels Length::viewport_relative_length_to_px(CSSPixelRect const& viewport_re
case Type::Svw:
case Type::Lvw:
case Type::Dvw:
- return viewport_rect.width() * (m_value / 100);
+ return CSSPixels(viewport_rect.width() * (m_value / 100));
case Type::Vh:
case Type::Svh:
case Type::Lvh:
case Type::Dvh:
- return viewport_rect.height() * (m_value / 100);
+ return CSSPixels(viewport_rect.height() * (m_value / 100));
case Type::Vi:
case Type::Svi:
case Type::Lvi:
case Type::Dvi:
// FIXME: Select the width or height based on which is the inline axis.
- return viewport_rect.width() * (m_value / 100);
+ return CSSPixels(viewport_rect.width() * (m_value / 100));
case Type::Vb:
case Type::Svb:
case Type::Lvb:
case Type::Dvb:
// FIXME: Select the width or height based on which is the block axis.
- return viewport_rect.height() * (m_value / 100);
+ return CSSPixels(viewport_rect.height() * (m_value / 100));
case Type::Vmin:
case Type::Svmin:
case Type::Lvmin:
case Type::Dvmin:
- return min(viewport_rect.width(), viewport_rect.height()) * (m_value / 100);
+ return CSSPixels(min(viewport_rect.width(), viewport_rect.height()) * (m_value / 100));
case Type::Vmax:
case Type::Svmax:
case Type::Lvmax:
case Type::Dvmax:
- return max(viewport_rect.width(), viewport_rect.height()) * (m_value / 100);
+ return CSSPixels(max(viewport_rect.width(), viewport_rect.height()) * (m_value / 100));
default:
VERIFY_NOT_REACHED();
}
@@ -138,8 +138,8 @@ Length::ResolutionContext Length::ResolutionContext::for_layout_node(Layout::Nod
VERIFY(root_element->layout_node());
return Length::ResolutionContext {
.viewport_rect = node.browsing_context().viewport_rect(),
- .font_metrics = { node.computed_values().font_size(), node.font().pixel_metrics(), node.line_height() },
- .root_font_metrics = { root_element->layout_node()->computed_values().font_size(), root_element->layout_node()->font().pixel_metrics(), root_element->layout_node()->line_height() },
+ .font_metrics = { CSSPixels(node.computed_values().font_size()), node.font().pixel_metrics(), node.line_height() },
+ .root_font_metrics = { CSSPixels(root_element->layout_node()->computed_values().font_size()), root_element->layout_node()->font().pixel_metrics(), root_element->layout_node()->line_height() },
};
}
@@ -168,12 +168,12 @@ CSSPixels Length::to_px(Layout::Node const& layout_node) const
return 0;
FontMetrics font_metrics {
- layout_node.computed_values().font_size(),
+ CSSPixels(layout_node.computed_values().font_size()),
layout_node.font().pixel_metrics(),
layout_node.line_height()
};
FontMetrics root_font_metrics {
- root_element->layout_node()->computed_values().font_size(),
+ CSSPixels(root_element->layout_node()->computed_values().font_size()),
root_element->layout_node()->font().pixel_metrics(),
root_element->layout_node()->line_height()
};
diff --git a/Userland/Libraries/LibWeb/CSS/Length.h b/Userland/Libraries/LibWeb/CSS/Length.h
index aeadd1276c..63da9b6ec3 100644
--- a/Userland/Libraries/LibWeb/CSS/Length.h
+++ b/Userland/Libraries/LibWeb/CSS/Length.h
@@ -185,19 +185,19 @@ public:
constexpr double centimeter_pixels = (inch_pixels / 2.54);
switch (m_type) {
case Type::Cm:
- return m_value * centimeter_pixels; // 1cm = 96px/2.54
+ return CSSPixels(m_value * centimeter_pixels); // 1cm = 96px/2.54
case Type::In:
- return m_value * inch_pixels; // 1in = 2.54 cm = 96px
+ return CSSPixels(m_value * inch_pixels); // 1in = 2.54 cm = 96px
case Type::Px:
- return m_value; // 1px = 1/96th of 1in
+ return CSSPixels(m_value); // 1px = 1/96th of 1in
case Type::Pt:
- return m_value * ((1.0 / 72.0) * inch_pixels); // 1pt = 1/72th of 1in
+ return CSSPixels(m_value * ((1.0 / 72.0) * inch_pixels)); // 1pt = 1/72th of 1in
case Type::Pc:
- return m_value * ((1.0 / 6.0) * inch_pixels); // 1pc = 1/6th of 1in
+ return CSSPixels(m_value * ((1.0 / 6.0) * inch_pixels)); // 1pc = 1/6th of 1in
case Type::Mm:
- return m_value * ((1.0 / 10.0) * centimeter_pixels); // 1mm = 1/10th of 1cm
+ return CSSPixels(m_value * ((1.0 / 10.0) * centimeter_pixels)); // 1mm = 1/10th of 1cm
case Type::Q:
- return m_value * ((1.0 / 40.0) * centimeter_pixels); // 1Q = 1/40th of 1cm
+ return CSSPixels(m_value * ((1.0 / 40.0) * centimeter_pixels)); // 1Q = 1/40th of 1cm
default:
VERIFY_NOT_REACHED();
}
diff --git a/Userland/Libraries/LibWeb/CSS/MediaQuery.cpp b/Userland/Libraries/LibWeb/CSS/MediaQuery.cpp
index 73a54b3ee2..33e43eb2a3 100644
--- a/Userland/Libraries/LibWeb/CSS/MediaQuery.cpp
+++ b/Userland/Libraries/LibWeb/CSS/MediaQuery.cpp
@@ -168,7 +168,7 @@ bool MediaFeature::compare(HTML::Window const& window, MediaFeatureValue left, C
auto const& initial_font = window.associated_document().style_computer().initial_font();
Gfx::FontPixelMetrics const& initial_font_metrics = initial_font.pixel_metrics();
- Length::FontMetrics font_metrics { static_cast(initial_font.presentation_size()), initial_font_metrics, initial_font_metrics.line_spacing() };
+ Length::FontMetrics font_metrics { CSSPixels(initial_font.presentation_size()), initial_font_metrics, CSSPixels(initial_font_metrics.line_spacing()) };
left_px = left.length().to_px(viewport_rect, font_metrics, font_metrics);
right_px = right.length().to_px(viewport_rect, font_metrics, font_metrics);
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
index 7b731b060b..f00b176ab6 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
@@ -1787,7 +1787,7 @@ Optional Parser::parse_dimension(ComponentValue const& component_valu
// FIXME: Disallow quirk when inside a CSS sub-expression (like `calc()`)
// "The value must not be supported in arguments to CSS expressions other than the rect()
// expression, and must not be supported in the supports() static method of the CSS interface."
- return Length::make_px(numeric_value);
+ return Length::make_px(CSSPixels(numeric_value));
}
}
diff --git a/Userland/Libraries/LibWeb/CSS/Position.cpp b/Userland/Libraries/LibWeb/CSS/Position.cpp
index 128d62ccac..f4e19c0a3b 100644
--- a/Userland/Libraries/LibWeb/CSS/Position.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Position.cpp
@@ -18,11 +18,11 @@ CSSPixelPoint PositionValue::resolved(Layout::Node const& node, CSSPixelRect con
return rect.width() * [&] {
switch (preset) {
case HorizontalPreset::Left:
- return 0.;
+ return CSSPixels(0.0);
case HorizontalPreset::Center:
- return 0.5;
+ return CSSPixels(0.5);
case HorizontalPreset::Right:
- return 1.;
+ return CSSPixels(1.0);
default:
VERIFY_NOT_REACHED();
}
@@ -36,11 +36,11 @@ CSSPixelPoint PositionValue::resolved(Layout::Node const& node, CSSPixelRect con
return rect.height() * [&] {
switch (preset) {
case VerticalPreset::Top:
- return 0.;
+ return CSSPixels(0.0);
case VerticalPreset::Center:
- return 0.5;
+ return CSSPixels(0.5);
case VerticalPreset::Bottom:
- return 1.;
+ return CSSPixels(1.0);
default:
VERIFY_NOT_REACHED();
}
diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp
index c2a3557912..5044fd73c5 100644
--- a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp
+++ b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp
@@ -596,7 +596,7 @@ RefPtr ResolvedCSSStyleDeclaration::style_value_for_property(L
case PropertyID::Float:
return IdentifierStyleValue::create(to_value_id(layout_node.computed_values().float_()));
case PropertyID::FontSize:
- return LengthStyleValue::create(Length::make_px(layout_node.computed_values().font_size()));
+ return LengthStyleValue::create(Length::make_px(CSSPixels(layout_node.computed_values().font_size())));
case PropertyID::FontVariant: {
auto font_variant = layout_node.computed_values().font_variant();
switch (font_variant) {
diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
index 42419bca1c..d1a71fa0ee 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
@@ -2036,7 +2036,7 @@ Length::FontMetrics StyleComputer::calculate_root_element_font_metrics(StyleProp
auto root_value = style.property(CSS::PropertyID::FontSize);
auto font_pixel_metrics = style.computed_font().pixel_metrics();
- Length::FontMetrics font_metrics { m_default_font_metrics.font_size, font_pixel_metrics, font_pixel_metrics.line_spacing() };
+ Length::FontMetrics font_metrics { m_default_font_metrics.font_size, font_pixel_metrics, CSSPixels(font_pixel_metrics.line_spacing()) };
font_metrics.font_size = root_value->as_length().length().to_px(viewport_rect(), font_metrics, font_metrics);
font_metrics.line_height = style.line_height(viewport_rect(), font_metrics, font_metrics);
@@ -2150,7 +2150,7 @@ RefPtr StyleComputer::compute_font_for_style_values(DOM::Elemen
bool bold = weight > Gfx::FontWeight::Regular;
// FIXME: Should be based on "user's default font size"
- float font_size_in_px = 16;
+ CSSPixels font_size_in_px = 16;
auto parent_line_height = parent_or_root_element_line_height(element, pseudo_element);
Gfx::FontPixelMetrics font_pixel_metrics;
@@ -2197,11 +2197,11 @@ RefPtr StyleComputer::compute_font_for_style_values(DOM::Elemen
// and smaller may compute the font size to the previous entry in the table.
if (identifier == CSS::ValueID::Smaller || identifier == CSS::ValueID::Larger) {
if (parent_element && parent_element->computed_css_values()) {
- font_size_in_px = parent_element->computed_css_values()->computed_font().pixel_metrics().size;
+ font_size_in_px = CSSPixels(parent_element->computed_css_values()->computed_font().pixel_metrics().size);
}
}
auto const multiplier = absolute_size_mapping.get(identifier).value_or(1.0);
- font_size_in_px *= multiplier;
+ font_size_in_px.scale_by(multiplier);
} else {
Length::ResolutionContext const length_resolution_context {
@@ -2213,7 +2213,7 @@ RefPtr StyleComputer::compute_font_for_style_values(DOM::Elemen
Optional maybe_length;
if (font_size.is_percentage()) {
// Percentages refer to parent element's font size
- maybe_length = Length::make_px(font_size.as_percentage().percentage().as_fraction() * parent_font_size().to_double());
+ maybe_length = Length::make_px(CSSPixels(font_size.as_percentage().percentage().as_fraction() * parent_font_size().to_double()));
} else if (font_size.is_length()) {
maybe_length = font_size.as_length().length();
@@ -2350,7 +2350,7 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
auto found_font = compute_font_for_style_values(element, pseudo_element, font_family, font_size, font_style, font_weight, font_stretch);
- style.set_property(CSS::PropertyID::FontSize, LengthStyleValue::create(CSS::Length::make_px(found_font->pixel_size())), nullptr);
+ style.set_property(CSS::PropertyID::FontSize, LengthStyleValue::create(CSS::Length::make_px(CSSPixels(found_font->pixel_size()))), nullptr);
style.set_property(CSS::PropertyID::FontWeight, NumberStyleValue::create(font_weight->to_font_weight()));
style.set_computed_font(found_font.release_nonnull());
@@ -2401,7 +2401,7 @@ void StyleComputer::absolutize_values(StyleProperties& style, DOM::Element const
auto line_height_value_slot = style.m_property_values[to_underlying(CSS::PropertyID::LineHeight)].map([](auto& x) -> auto& { return x.style; });
if (line_height_value_slot.has_value() && (*line_height_value_slot)->is_percentage()) {
*line_height_value_slot = LengthStyleValue::create(
- Length::make_px(font_size * static_cast((*line_height_value_slot)->as_percentage().percentage().as_fraction())));
+ Length::make_px(CSSPixels(font_size * static_cast((*line_height_value_slot)->as_percentage().percentage().as_fraction()))));
}
auto line_height = style.line_height(viewport_rect(), font_metrics, m_root_element_font_metrics);
diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp
index 070ac195d2..69f7e649cc 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp
@@ -204,7 +204,7 @@ CSSPixels StyleProperties::line_height(Layout::Node const& layout_node) const
auto line_height = property(CSS::PropertyID::LineHeight);
if (line_height->is_identifier() && line_height->to_identifier() == ValueID::Normal)
- return layout_node.font().pixel_metrics().line_spacing();
+ return CSSPixels(layout_node.font().pixel_metrics().line_spacing());
if (line_height->is_length()) {
auto line_height_length = line_height->as_length().length();
@@ -226,7 +226,7 @@ CSSPixels StyleProperties::line_height(Layout::Node const& layout_node) const
auto resolved = line_height->as_calculated().resolve_number();
if (!resolved.has_value()) {
dbgln("FIXME: Failed to resolve calc() line-height (number): {}", line_height->as_calculated().to_string());
- return layout_node.font().pixel_metrics().line_spacing();
+ return CSSPixels(layout_node.font().pixel_metrics().line_spacing());
}
return Length(resolved.value(), Length::Type::Em).to_px(layout_node);
}
@@ -234,12 +234,12 @@ CSSPixels StyleProperties::line_height(Layout::Node const& layout_node) const
auto resolved = line_height->as_calculated().resolve_length(layout_node);
if (!resolved.has_value()) {
dbgln("FIXME: Failed to resolve calc() line-height: {}", line_height->as_calculated().to_string());
- return layout_node.font().pixel_metrics().line_spacing();
+ return CSSPixels(layout_node.font().pixel_metrics().line_spacing());
}
return resolved->to_px(layout_node);
}
- return layout_node.font().pixel_metrics().line_spacing();
+ return CSSPixels(layout_node.font().pixel_metrics().line_spacing());
}
Optional StyleProperties::z_index() const
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp
index d7343e0334..5a47eaa499 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp
@@ -77,7 +77,7 @@ static CalculatedStyleValue::CalculationResult to_resolved_type(CalculatedStyleV
case CalculatedStyleValue::ResolvedType::Frequency:
return { Frequency::make_hertz(value) };
case CalculatedStyleValue::ResolvedType::Length:
- return { Length::make_px(value) };
+ return { Length::make_px(CSSPixels(value)) };
case CalculatedStyleValue::ResolvedType::Percentage:
return { Percentage(value) };
case CalculatedStyleValue::ResolvedType::Time:
@@ -2155,7 +2155,7 @@ void CalculatedStyleValue::CalculationResult::multiply_by(CalculationResult cons
m_value = Frequency::make_hertz(frequency.to_hertz() * other.m_value.get().value());
},
[&](Length const& length) {
- m_value = Length::make_px(length.to_px(*context) * static_cast(other.m_value.get().value()));
+ m_value = Length::make_px(CSSPixels(length.to_px(*context) * static_cast(other.m_value.get().value())));
},
[&](Time const& time) {
m_value = Time::make_seconds(time.to_seconds() * other.m_value.get().value());
@@ -2187,7 +2187,7 @@ void CalculatedStyleValue::CalculationResult::divide_by(CalculationResult const&
m_value = Frequency::make_hertz(frequency.to_hertz() / denominator);
},
[&](Length const& length) {
- m_value = Length::make_px(length.to_px(*context) / static_cast(denominator));
+ m_value = Length::make_px(CSSPixels(length.to_px(*context) / static_cast(denominator)));
},
[&](Time const& time) {
m_value = Time::make_seconds(time.to_seconds() / denominator);
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp
index ed547d42b1..ad02e79834 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp
@@ -150,8 +150,8 @@ Gfx::FloatSize RadialGradientStyleValue::resolve_size(Layout::Node const& node,
return Gfx::FloatSize { radius.to_float(), radius.to_float() };
},
[&](EllipseSize const& ellipse_size) {
- auto radius_a = ellipse_size.radius_a.resolved(node, CSS::Length::make_px(size.width())).to_px(node);
- auto radius_b = ellipse_size.radius_b.resolved(node, CSS::Length::make_px(size.height())).to_px(node);
+ auto radius_a = ellipse_size.radius_a.resolved(node, CSS::Length::make_px(CSSPixels(size.width()))).to_px(node);
+ auto radius_b = ellipse_size.radius_b.resolved(node, CSS::Length::make_px(CSSPixels(size.height()))).to_px(node);
return Gfx::FloatSize { radius_a.to_float(), radius_b.to_float() };
});
diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp
index 3c1e38883b..2bcc7fb1c0 100644
--- a/Userland/Libraries/LibWeb/DOM/Element.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Element.cpp
@@ -1085,7 +1085,7 @@ void Element::set_scroll_left(double x)
// 11. Scroll the element to x,scrollTop, with the scroll behavior being "auto".
// FIXME: Implement this in terms of calling "scroll the element".
auto scroll_offset = paintable_box()->scroll_offset();
- scroll_offset.set_x(static_cast(x));
+ scroll_offset.set_x(CSSPixels(x));
paintable_box()->set_scroll_offset(scroll_offset);
}
@@ -1153,7 +1153,7 @@ void Element::set_scroll_top(double y)
// 11. Scroll the element to scrollLeft,y, with the scroll behavior being "auto".
// FIXME: Implement this in terms of calling "scroll the element".
auto scroll_offset = paintable_box()->scroll_offset();
- scroll_offset.set_y(static_cast(y));
+ scroll_offset.set_y(CSSPixels(y));
paintable_box()->set_scroll_offset(scroll_offset);
}
diff --git a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp
index 711b7cea44..62e930e47d 100644
--- a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp
@@ -3993,14 +3993,14 @@ static RefPtr parse_current_dimension_value(float value, Utf8Vi
{
// 1. If position is past the end of input, then return value as a length.
if (position == input.end())
- return CSS::LengthStyleValue::create(CSS::Length::make_px(value));
+ return CSS::LengthStyleValue::create(CSS::Length::make_px(CSSPixels(value)));
// 2. If the code point at position within input is U+0025 (%), then return value as a percentage.
if (*position == '%')
return CSS::PercentageStyleValue::create(CSS::Percentage(value));
// 3. Return value as a length.
- return CSS::LengthStyleValue::create(CSS::Length::make_px(value));
+ return CSS::LengthStyleValue::create(CSS::Length::make_px(CSSPixels(value)));
}
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-dimension-values
@@ -4065,7 +4065,7 @@ RefPtr parse_dimension_value(StringView string)
// 4. If position is past the end of input, then return value as a length.
if (position == input.end())
- return CSS::LengthStyleValue::create(CSS::Length::make_px(value));
+ return CSS::LengthStyleValue::create(CSS::Length::make_px(CSSPixels(value)));
// 5. If the code point at position within input is not an ASCII digit, then break.
if (!is_ascii_digit(*position))
diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp
index cd08351429..0ae92b2f2a 100644
--- a/Userland/Libraries/LibWeb/HTML/Window.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Window.cpp
@@ -481,12 +481,12 @@ Optional Window::query_media_feature(CSS::MediaFeatureID
// FIXME: device-aspect-ratio
case CSS::MediaFeatureID::DeviceHeight:
if (auto* page = this->page()) {
- return CSS::MediaFeatureValue(CSS::Length::make_px(page->web_exposed_screen_area().height().to_double()));
+ return CSS::MediaFeatureValue(CSS::Length::make_px(page->web_exposed_screen_area().height()));
}
return CSS::MediaFeatureValue(0);
case CSS::MediaFeatureID::DeviceWidth:
if (auto* page = this->page()) {
- return CSS::MediaFeatureValue(CSS::Length::make_px(page->web_exposed_screen_area().width().to_double()));
+ return CSS::MediaFeatureValue(CSS::Length::make_px(page->web_exposed_screen_area().width()));
}
return CSS::MediaFeatureValue(0);
case CSS::MediaFeatureID::DisplayMode:
diff --git a/Userland/Libraries/LibWeb/Layout/AvailableSpace.h b/Userland/Libraries/LibWeb/Layout/AvailableSpace.h
index a15aad7a91..0e665de694 100644
--- a/Userland/Libraries/LibWeb/Layout/AvailableSpace.h
+++ b/Userland/Libraries/LibWeb/Layout/AvailableSpace.h
@@ -36,7 +36,7 @@ public:
CSSPixels to_px_or_zero() const
{
if (!is_definite())
- return 0.0f;
+ return 0;
return m_value;
}
diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
index 878b22b998..fc2a650e89 100644
--- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
@@ -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 + text_width);
+ marker_state.set_content_width(image_width + CSSPixels(text_width));
}
marker_state.set_content_height(max(image_height, marker.font().pixel_size_rounded_up() + 1));
diff --git a/Userland/Libraries/LibWeb/Layout/ButtonBox.cpp b/Userland/Libraries/LibWeb/Layout/ButtonBox.cpp
index 0bdf09a67f..a68dac2fb1 100644
--- a/Userland/Libraries/LibWeb/Layout/ButtonBox.cpp
+++ b/Userland/Libraries/LibWeb/Layout/ButtonBox.cpp
@@ -25,7 +25,7 @@ void ButtonBox::prepare_for_replaced_layout()
// value attribute. This is not the case with , which contains
// its contents normally.
if (is(dom_node())) {
- set_natural_width(font().width(static_cast(dom_node()).value()));
+ set_natural_width(CSSPixels(font().width(static_cast(dom_node()).value())));
set_natural_height(font().pixel_size_rounded_up());
}
}
diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
index 67ce546c95..e9050966e2 100644
--- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
@@ -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 cross_size * aspect_ratio;
- return cross_size / aspect_ratio;
+ return CSSPixels(cross_size * aspect_ratio);
+ return CSSPixels(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 main_size / aspect_ratio;
- return main_size * aspect_ratio;
+ return CSSPixels(main_size / aspect_ratio);
+ return CSSPixels(main_size * aspect_ratio);
}
// This function takes a size in the main axis and adjusts it according to the aspect ratio of the box
@@ -687,7 +687,7 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size(
// The hypothetical main size is the item’s flex base size clamped according to its used min and max main sizes (and flooring the content box size at zero).
auto clamp_min = has_main_min_size(child_box) ? specified_main_min_size(child_box) : automatic_minimum_size(item);
- auto clamp_max = has_main_max_size(child_box) ? specified_main_max_size(child_box) : NumericLimits::max();
+ auto clamp_max = has_main_max_size(child_box) ? specified_main_max_size(child_box) : CSSPixels::max();
item.hypothetical_main_size = max(CSSPixels(0), css_clamp(item.flex_base_size, clamp_min, clamp_max));
// NOTE: At this point, we set the hypothetical main size as the flex item's *temporary* main size.
@@ -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 = initial_free_space.value() * sum_of_flex_factor_of_unfrozen_items;
+ auto value = CSSPixels(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;
@@ -1004,7 +1004,7 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
continue;
double ratio = item.flex_factor.value() / sum_of_flex_factor_of_unfrozen_items;
// Set the item’s target main size to its flex base size plus a fraction of the remaining free space proportional to the ratio.
- item.target_main_size = item.flex_base_size + (remaining_free_space_or_zero_if_infinite * ratio);
+ item.target_main_size = item.flex_base_size + remaining_free_space_or_zero_if_infinite.scaled(ratio);
}
}
// If using the flex shrink factor
@@ -1026,7 +1026,7 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
// Set the item’s target main size to its flex base size minus a fraction of the absolute value of the remaining free space proportional to the ratio.
// (Note this may result in a negative inner main size; it will be corrected in the next step.)
- item.target_main_size = item.flex_base_size - (abs(remaining_free_space_or_zero_if_infinite) * ratio);
+ item.target_main_size = item.flex_base_size - abs(remaining_free_space_or_zero_if_infinite).scaled(ratio);
}
}
}
@@ -1044,7 +1044,7 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
auto used_max_main_size = has_main_max_size(item.box)
? specified_main_max_size(item.box)
- : NumericLimits::max();
+ : CSSPixels::max();
auto original_target_main_size = item.target_main_size;
item.target_main_size = css_clamp(item.target_main_size, used_min_main_size, used_max_main_size);
@@ -1123,7 +1123,7 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem&
auto const& computed_max_size = this->computed_cross_max_size(item.box);
auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0;
- auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits::max();
+ auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : CSSPixels::max();
// If we have a definite cross size, this is easy! No need to perform layout, we can just use it as-is.
if (has_definite_cross_size(item.box)) {
@@ -1339,7 +1339,7 @@ void FlexFormattingContext::distribute_any_remaining_free_space()
}
break;
case CSS::JustifyContent::Center:
- initial_offset = (inner_main_size(flex_container()) - used_main_space) / 2.0;
+ initial_offset = (inner_main_size(flex_container()) - used_main_space) / 2;
if (is_direction_reverse()) {
initial_offset = inner_main_size(flex_container()) - initial_offset;
}
@@ -1357,9 +1357,9 @@ void FlexFormattingContext::distribute_any_remaining_free_space()
if (flex_line.remaining_free_space.has_value())
space_between_items = flex_line.remaining_free_space.value() / number_of_items;
if (is_direction_reverse()) {
- initial_offset = inner_main_size(flex_container()) - space_between_items / 2.0;
+ initial_offset = inner_main_size(flex_container()) - space_between_items / 2;
} else {
- initial_offset = space_between_items / 2.0;
+ initial_offset = space_between_items / 2;
}
break;
case CSS::JustifyContent::SpaceEvenly:
@@ -1496,7 +1496,7 @@ void FlexFormattingContext::align_all_flex_items_along_the_cross_axis()
// FIXME: Take better care of margins
for (auto& flex_line : m_flex_lines) {
for (auto& item : flex_line.items) {
- CSSPixels half_line_size = flex_line.cross_size / 2.0;
+ CSSPixels half_line_size = flex_line.cross_size / 2;
switch (alignment_for_item(item.box)) {
case CSS::AlignItems::Baseline:
// FIXME: Implement this
@@ -1512,7 +1512,7 @@ void FlexFormattingContext::align_all_flex_items_along_the_cross_axis()
item.cross_offset = half_line_size - item.cross_size.value() - item.margins.cross_after - item.borders.cross_after - item.padding.cross_after;
break;
case CSS::AlignItems::Center:
- item.cross_offset = -(item.cross_size.value() / 2.0);
+ item.cross_offset = -(item.cross_size.value() / 2);
break;
default:
break;
@@ -1573,7 +1573,7 @@ void FlexFormattingContext::align_all_flex_lines()
if (is_single_line()) {
// For single-line flex containers, we only need to center the line along the cross axis.
auto& flex_line = m_flex_lines[0];
- CSSPixels center_of_line = cross_size_of_flex_container / 2.0;
+ CSSPixels center_of_line = cross_size_of_flex_container / 2;
for (auto& item : flex_line.items) {
item.cross_offset += center_of_line;
}
@@ -1732,15 +1732,15 @@ CSSPixels FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container
CSSPixels result = contribution - outer_flex_base_size;
if (result > 0) {
if (item.box->computed_values().flex_grow() >= 1) {
- result /= item.box->computed_values().flex_grow();
+ result.scale_by(1 / item.box->computed_values().flex_grow());
} else {
- result *= item.box->computed_values().flex_grow();
+ result.scale_by(item.box->computed_values().flex_grow());
}
} else if (result < 0) {
if (item.scaled_flex_shrink_factor == 0)
result = CSSPixels::min();
else
- result /= item.scaled_flex_shrink_factor;
+ result.scale_by(1 / item.scaled_flex_shrink_factor);
}
item.desired_flex_fraction = result.to_double();
@@ -1793,13 +1793,13 @@ CSSPixels FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container
product = flex_line.chosen_flex_fraction * static_cast(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 + product;
+ auto result = item.flex_base_size + CSSPixels(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);
auto clamp_min = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
- auto clamp_max = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_main_max_size(item.box) : NumericLimits::max();
+ auto clamp_max = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_main_max_size(item.box) : CSSPixels::max();
result = css_clamp(result, clamp_min, clamp_max);
@@ -1906,7 +1906,7 @@ CSSPixels FlexFormattingContext::calculate_main_min_content_contribution(FlexIte
}();
auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
- auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits::max();
+ auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : CSSPixels::max();
auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
return item.add_main_margin_box_sizes(clamped_inner_size);
@@ -1927,7 +1927,7 @@ CSSPixels FlexFormattingContext::calculate_main_max_content_contribution(FlexIte
}();
auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
- auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits::max();
+ auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : CSSPixels::max();
auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
return item.add_main_margin_box_sizes(clamped_inner_size);
@@ -1959,7 +1959,7 @@ CSSPixels FlexFormattingContext::calculate_cross_min_content_contribution(FlexIt
auto const& computed_max_size = this->computed_cross_max_size(item.box);
auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0;
- auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits::max();
+ auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : CSSPixels::max();
auto clamped_inner_size = css_clamp(size, clamp_min, clamp_max);
@@ -1978,7 +1978,7 @@ CSSPixels FlexFormattingContext::calculate_cross_max_content_contribution(FlexIt
auto const& computed_max_size = this->computed_cross_max_size(item.box);
auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0;
- auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits::max();
+ auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : CSSPixels::max();
auto clamped_inner_size = css_clamp(size, clamp_min, clamp_max);
@@ -1992,7 +1992,7 @@ CSSPixels FlexFormattingContext::calculate_width_to_use_when_determining_intrins
auto const& computed_min_width = box.computed_values().min_width();
auto const& computed_max_width = box.computed_values().max_width();
auto clamp_min = (!computed_min_width.is_auto() && (!computed_min_width.contains_percentage())) ? specified_cross_min_size(box) : 0;
- auto clamp_max = (!computed_max_width.is_none() && (!computed_max_width.contains_percentage())) ? specified_cross_max_size(box) : NumericLimits::max();
+ auto clamp_max = (!computed_max_width.is_none() && (!computed_max_width.contains_percentage())) ? specified_cross_max_size(box) : CSSPixels::max();
CSSPixels width;
if (should_treat_width_as_auto(box, m_available_space_for_items->space) || computed_width.is_fit_content())
@@ -2123,8 +2123,8 @@ void FlexFormattingContext::resolve_cross_axis_auto_margins()
if (outer_cross_size < line.cross_size) {
CSSPixels remainder = line.cross_size - outer_cross_size;
if (item.margins.cross_before_is_auto && item.margins.cross_after_is_auto) {
- item.margins.cross_before = remainder / 2.0;
- item.margins.cross_after = remainder / 2.0;
+ item.margins.cross_before = remainder / 2;
+ item.margins.cross_after = remainder / 2;
} else if (item.margins.cross_before_is_auto) {
item.margins.cross_before = remainder;
} else {
@@ -2203,13 +2203,13 @@ CSSPixelPoint FlexFormattingContext::calculate_static_position(Box const& box) c
cross_offset = half_line_size - inner_cross_size(box) - cross_margin_after - cross_border_after - cross_padding_after;
break;
case CSS::AlignItems::Center:
- cross_offset = -((inner_cross_size(box) + cross_border_before + cross_border_after) / 2.0);
+ cross_offset = -((inner_cross_size(box) + cross_border_before + cross_border_after) / 2);
break;
default:
break;
}
- cross_offset += inner_cross_size(flex_container()) / 2.0;
+ cross_offset += inner_cross_size(flex_container()) / 2;
// The main-axis edges of the static-position rectangle are where the margin edges of the child
// would be positioned if it were the sole flex item in the flex container,
@@ -2236,7 +2236,7 @@ CSSPixelPoint FlexFormattingContext::calculate_static_position(Box const& box) c
case CSS::JustifyContent::SpaceAround:
case CSS::JustifyContent::SpaceEvenly:
pack_from_end = false;
- main_offset = (inner_main_size(flex_container()) - inner_main_size(box) - main_border_before - main_border_after) / 2.0;
+ main_offset = (inner_main_size(flex_container()) - inner_main_size(box) - main_border_before - main_border_after) / 2;
break;
}
diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
index 97ee7b6cc6..d74e26e951 100644
--- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
@@ -405,7 +405,7 @@ CSSPixels FormattingContext::tentative_width_for_replaced_element(Box const& box
// (used height) * (intrinsic ratio)
if ((computed_height.is_auto() && computed_width.is_auto() && !box.has_natural_width() && box.has_natural_height() && box.has_preferred_aspect_ratio())
|| (computed_width.is_auto() && !computed_height.is_auto() && box.has_preferred_aspect_ratio())) {
- return compute_height_for_replaced_element(box, available_space) * static_cast(box.preferred_aspect_ratio().value());
+ return compute_height_for_replaced_element(box, available_space).scaled(static_cast(box.preferred_aspect_ratio().value()));
}
// If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width,
@@ -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 m_state.get(box).content_width() / static_cast(box.preferred_aspect_ratio().value());
+ return CSSPixels(m_state.get(box).content_width() / static_cast(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())
@@ -1051,8 +1051,8 @@ CSSPixelPoint FormattingContext::calculate_static_position(Box const& box) const
// The purpose of this function is to calculate the approximate position that `box`
// would have had if it were position:static.
- CSSPixels x = 0.0f;
- CSSPixels y = 0.0f;
+ CSSPixels x = 0;
+ CSSPixels y = 0;
VERIFY(box.parent());
if (box.parent()->children_are_inline()) {
@@ -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 width / static_cast(*box.preferred_aspect_ratio());
+ return CSSPixels(width / static_cast(*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 box.computed_values().font_size();
+ return CSSPixels(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() - (box.containing_block()->font().pixel_metrics().descent * 2);
+ return box_state.content_height() - CSSPixels(box.containing_block()->font().pixel_metrics().descent * 2);
default:
break;
}
diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
index a3c4a7d4c0..3d4cefe35a 100644
--- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
@@ -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, track.base_size / track.max_track_sizing_function.flex_factor());
+ result = max(result, CSSPixels(track.base_size / track.max_track_sizing_function.flex_factor()));
} else {
result = max(result, track.base_size);
}
@@ -1273,8 +1273,8 @@ void GridFormattingContext::expand_flexible_tracks(AvailableSpace const& availab
// For each flexible track, if the product of the used flex fraction and the track’s flex factor is greater than
// the track’s base size, set its base size to that product.
for (auto& track : tracks_and_gaps) {
- if (track.max_track_sizing_function.flex_factor() * flex_fraction > track.base_size) {
- track.base_size = track.max_track_sizing_function.flex_factor() * flex_fraction;
+ if (flex_fraction.scaled(track.max_track_sizing_function.flex_factor()) > track.base_size) {
+ track.base_size = flex_fraction.scaled(track.max_track_sizing_function.flex_factor());
}
}
}
diff --git a/Userland/Libraries/LibWeb/Layout/ImageBox.cpp b/Userland/Libraries/LibWeb/Layout/ImageBox.cpp
index 50e60b1e43..67c82dc03a 100644
--- a/Userland/Libraries/LibWeb/Layout/ImageBox.cpp
+++ b/Userland/Libraries/LibWeb/Layout/ImageBox.cpp
@@ -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 = font.width(alt);
+ m_cached_alt_text_width = CSSPixels(font.width(alt));
alt_text_width = m_cached_alt_text_width.value();
set_natural_width(alt_text_width + 16);
- set_natural_height(font.pixel_size() + 16);
+ set_natural_height(CSSPixels(font.pixel_size()) + 16);
}
if (!has_natural_width() && !has_natural_height()) {
diff --git a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp
index 1bbc56772a..a9a6839d9d 100644
--- a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp
+++ b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp
@@ -180,7 +180,7 @@ Optional InlineLevelIterator::next_without_lookahead(
m_text_node_context->is_last_chunk = true;
auto& chunk = chunk_opt.value();
- CSSPixels chunk_width = text_node.font().width(chunk.view) + text_node.font().glyph_spacing();
+ CSSPixels chunk_width = CSSPixels(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 {
diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp
index 083f19c802..b3f3fcf769 100644
--- a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp
+++ b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp
@@ -386,7 +386,7 @@ void LayoutState::UsedValues::set_node(NodeWithStyleAndBoxModelMetrics& node, Us
if (size.is_percentage()) {
if (containing_block_has_definite_size) {
auto containing_block_size = width ? containing_block_used_values->content_width() : containing_block_used_values->content_height();
- resolved_definite_size = adjust_for_box_sizing(containing_block_size * static_cast(size.percentage().as_fraction()), size, width);
+ resolved_definite_size = adjust_for_box_sizing(containing_block_size.scaled(size.percentage().as_fraction()), size, width);
return true;
}
return false;
diff --git a/Userland/Libraries/LibWeb/Layout/LineBox.cpp b/Userland/Libraries/LibWeb/Layout/LineBox.cpp
index cf68b6e559..cd707a242a 100644
--- a/Userland/Libraries/LibWeb/Layout/LineBox.cpp
+++ b/Userland/Libraries/LibWeb/Layout/LineBox.cpp
@@ -25,7 +25,7 @@ void LineBox::add_fragment(Node const& layout_node, int start, int length, CSSPi
m_fragments.last().set_width(m_fragments.last().width() + content_width);
} else {
CSSPixels x_offset = leading_margin + leading_size + m_width;
- CSSPixels y_offset = 0.0f;
+ CSSPixels y_offset = 0;
m_fragments.append(LineBoxFragment { layout_node, start, length, CSSPixelPoint(x_offset, y_offset), CSSPixelSize(content_width, content_height), border_box_top, border_box_bottom });
}
m_width += leading_margin + leading_size + content_width + trailing_size + trailing_margin;
diff --git a/Userland/Libraries/LibWeb/Layout/LineBoxFragment.cpp b/Userland/Libraries/LibWeb/Layout/LineBoxFragment.cpp
index 0b198015c5..06c03bb014 100644
--- a/Userland/Libraries/LibWeb/Layout/LineBoxFragment.cpp
+++ b/Userland/Libraries/LibWeb/Layout/LineBoxFragment.cpp
@@ -51,7 +51,7 @@ int LineBoxFragment::text_index_at(CSSPixels x) const
Utf8View view(text());
CSSPixels relative_x = x - absolute_x();
- float glyph_spacing = font.glyph_spacing();
+ CSSPixels glyph_spacing = CSSPixels(font.glyph_spacing());
if (relative_x < 0)
return 0;
@@ -59,9 +59,9 @@ 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 = font.glyph_or_emoji_width(it);
+ CSSPixels glyph_width = CSSPixels(font.glyph_or_emoji_width(it));
- if ((width_so_far + (glyph_width + glyph_spacing) / 2) > relative_x)
+ if ((width_so_far + glyph_width + glyph_spacing / 2) > relative_x)
return m_start + view.byte_offset_of(previous_it);
width_so_far += glyph_width + glyph_spacing;
@@ -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 = font.width(text.substring_view(0, selection_start_in_this_fragment));
- auto pixel_width_of_selection = 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(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 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 = font.width(text.substring_view(0, selection_start_in_this_fragment));
- auto pixel_width_of_selection = 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(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 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 = font.width(text.substring_view(0, selection_start_in_this_fragment));
- auto pixel_width_of_selection = 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(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 rect = absolute_rect();
rect.set_x(rect.x() + pixel_distance_to_first_selected_character);
diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp
index 69ae43841c..9c92fcaaf5 100644
--- a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp
+++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp
@@ -195,7 +195,7 @@ 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 = font_metrics.ascent + font_metrics.descent;
+ auto const typographic_height = CSSPixels(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;
@@ -230,7 +230,7 @@ void LineBuilder::update_last_line()
if (length_percentage->is_length())
fragment_baseline += length_percentage->length().to_px(fragment.layout_node());
else if (length_percentage->is_percentage())
- fragment_baseline += length_percentage->percentage().as_fraction() * line_height.to_double();
+ fragment_baseline += line_height.scaled(length_percentage->percentage().as_fraction());
}
line_box_baseline = max(line_box_baseline, fragment_baseline);
@@ -284,7 +284,7 @@ void LineBuilder::update_last_line()
auto vertical_align_amount = length_percentage->length().to_px(fragment.layout_node());
new_fragment_y = y_value_for_alignment(CSS::VerticalAlign::Baseline) - vertical_align_amount;
} else if (length_percentage->is_percentage()) {
- auto vertical_align_amount = length_percentage->percentage().as_fraction() * m_context.containing_block().line_height().to_double();
+ auto vertical_align_amount = m_context.containing_block().line_height().scaled(length_percentage->percentage().as_fraction());
new_fragment_y = y_value_for_alignment(CSS::VerticalAlign::Baseline) - vertical_align_amount;
}
}
@@ -302,17 +302,17 @@ 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 = font_metrics.ascent + font_metrics.descent;
+ auto typographic_height = CSSPixels(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() - font_metrics.ascent - half_leading);
- bottom_of_inline_box = (fragment.offset().y() + fragment.baseline() + font_metrics.descent + half_leading);
+ 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);
}
if (auto const* length_percentage = fragment.layout_node().computed_values().vertical_align().get_pointer()) {
if (length_percentage->is_length())
bottom_of_inline_box += length_percentage->length().to_px(fragment.layout_node());
else if (length_percentage->is_percentage())
- bottom_of_inline_box += length_percentage->percentage().as_fraction() * m_context.containing_block().line_height().to_double();
+ bottom_of_inline_box += m_context.containing_block().line_height().scaled(length_percentage->percentage().as_fraction());
}
}
diff --git a/Userland/Libraries/LibWeb/Layout/Node.cpp b/Userland/Libraries/LibWeb/Layout/Node.cpp
index f51815860d..dfd3d677f9 100644
--- a/Userland/Libraries/LibWeb/Layout/Node.cpp
+++ b/Userland/Libraries/LibWeb/Layout/Node.cpp
@@ -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 1 / device_pixels_per_css_pixel;
+ return CSSPixels(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 CSSPixels(floor(device_pixels) / device_pixels_per_css_pixel);
return length;
}
@@ -684,11 +684,11 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
// https://www.w3.org/TR/css-backgrounds-3/#valdef-line-width-thin
switch (value->to_identifier()) {
case CSS::ValueID::Thin:
- return 1.0;
+ return 1;
case CSS::ValueID::Medium:
- return 3.0;
+ return 3;
case CSS::ValueID::Thick:
- return 5.0;
+ return 5;
default:
VERIFY_NOT_REACHED();
}
@@ -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(stroke_width->as_number().number()));
+ computed_values.set_stroke_width(CSS::Length::make_px(CSSPixels(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())
diff --git a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp
index cd1432df6c..26be31444b 100644
--- a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp
@@ -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() - (view_box.width * viewbox_transform.scale_factor)) / 2, 0);
+ viewbox_transform.offset.translate_by((svg_box_state.content_width() - CSSPixels(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 + of the element's ‘viewBox’ with the maximum X value of the SVG viewport.
- viewbox_transform.offset.translate_by((svg_box_state.content_width() - (view_box.width * viewbox_transform.scale_factor)), 0);
+ viewbox_transform.offset.translate_by((svg_box_state.content_width() - CSSPixels(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() - (view_box.height * viewbox_transform.scale_factor)) / 2);
+ viewbox_transform.offset.translate_by(0, (svg_box_state.content_height() - CSSPixels(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 + 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() - (view_box.height * viewbox_transform.scale_factor)));
+ viewbox_transform.offset.translate_by(0, (svg_box_state.content_height() - CSSPixels(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 stroke_width = static_cast(geometry_box.dom_node().visible_stroke_width()) * viewbox_scale;
+ CSSPixels stroke_width = CSSPixels(static_cast(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());
diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp
index 44918d5b29..d23c71079f 100644
--- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp
@@ -265,11 +265,11 @@ void TableFormattingContext::compute_intrinsic_percentage(size_t max_cell_span)
auto cell_start_rc_index = cell_index(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 = cell_percentage_contribution(cell);
+ CSSPixels cell_contribution = CSSPixels(cell_percentage_contribution(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 -= rows_or_columns[rc_index].intrinsic_percentage;
+ cell_contribution -= CSSPixels(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
@@ -297,7 +297,7 @@ void TableFormattingContext::compute_intrinsic_percentage(size_t max_cell_span)
// columns spanned by the cell that have an intrinsic percentage width of the column based on cells of span up to N-1 equal to 0%.
CSSPixels ajusted_cell_contribution;
if (width_sum_of_columns_with_zero_intrinsic_percentage != 0) {
- ajusted_cell_contribution = cell_contribution * rows_or_columns[rc_index].max_size / static_cast(width_sum_of_columns_with_zero_intrinsic_percentage);
+ ajusted_cell_contribution = cell_contribution.scaled(rows_or_columns[rc_index].max_size / static_cast(width_sum_of_columns_with_zero_intrinsic_percentage));
} else {
// However, if this ratio is undefined because the denominator is zero, instead use the 1 divided by the number of columns
// spanned by the cell that have an intrinsic percentage width of the column based on cells of span up to N-1 equal to zero.
@@ -380,12 +380,12 @@ void TableFormattingContext::compute_table_measures()
auto clamped_diff_to_baseline_min = min(
max(cell_min_size(cell) - baseline_min_content_size - baseline_border_spacing, 0),
baseline_max_content_size - baseline_min_content_size);
- cell_min_contribution += normalized_max_min_diff * clamped_diff_to_baseline_min;
+ cell_min_contribution += CSSPixels(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 += (rows_or_columns[rc_index].max_size / static_cast(baseline_max_content_size))
+ cell_min_contribution += CSSPixels(rows_or_columns[rc_index].max_size / static_cast(baseline_max_content_size))
* max(CSSPixels(0), cell_min_size(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 += (rows_or_columns[rc_index].max_size / static_cast(baseline_max_content_size))
+ cell_max_contribution += CSSPixels(rows_or_columns[rc_index].max_size / static_cast(baseline_max_content_size))
* max(CSSPixels(0), cell_max_size(cell) - baseline_max_content_size - baseline_border_spacing);
}
cell_min_contributions_by_rc_index[rc_index].append(cell_min_contribution);
@@ -461,7 +461,7 @@ void TableFormattingContext::compute_table_width()
// The row/column-grid width minimum (GRIDMIN) width is the sum of the min-content width
// of all the columns plus cell spacing or borders.
- CSSPixels grid_min = 0.0f;
+ CSSPixels grid_min = 0;
for (auto& column : m_columns) {
grid_min += column.min_size;
}
@@ -469,7 +469,7 @@ void TableFormattingContext::compute_table_width()
// The row/column-grid width maximum (GRIDMAX) width is the sum of the max-content width
// of all the columns plus cell spacing or borders.
- CSSPixels grid_max = 0.0f;
+ CSSPixels grid_max = 0;
for (auto& column : m_columns) {
grid_max += column.max_size;
}
@@ -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 = ceil(100 / cell_width.percentage().value() * cell.outer_max_width.to_double());
+ adjusted_used_width = CSSPixels(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(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 = candidate_weight * candidate_widths[i] + (1 - candidate_weight) * column.used_width;
+ column.used_width = CSSPixels(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 += excess_width * base_width_getter(column) / static_cast(total_base_width);
+ column.used_width += CSSPixels(excess_width * base_width_getter(column) / static_cast(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 += excess_width * column.intrinsic_percentage / total_percentage_width;
+ column.used_width += CSSPixels(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, column.intrinsic_percentage / 100 * available_width);
+ candidate_widths[i] = max(column.min_size, CSSPixels(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(sum_reference_height);
auto final_height = m_table_height * weight;
- row.final_height = final_height;
+ row.final_height = CSSPixels(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
@@ -1029,7 +1029,7 @@ void TableFormattingContext::position_row_boxes()
for (size_t y = 0; y < m_rows.size(); y++) {
auto& row = m_rows[y];
auto& row_state = m_state.get_mutable(row.box);
- CSSPixels row_width = 0.0f;
+ CSSPixels row_width = 0;
for (auto& column : m_columns) {
row_width += column.used_width;
}
@@ -1044,8 +1044,8 @@ void TableFormattingContext::position_row_boxes()
CSSPixels row_group_top_offset = table_state.border_top + table_state.padding_top;
CSSPixels row_group_left_offset = table_state.border_left + table_state.padding_left;
TableGrid::for_each_child_box_matching(table_box(), TableGrid::is_table_row_group, [&](auto& row_group_box) {
- CSSPixels row_group_height = 0.0f;
- CSSPixels row_group_width = 0.0f;
+ CSSPixels row_group_height = 0;
+ CSSPixels row_group_width = 0;
auto& row_group_box_state = m_state.get_mutable(row_group_box);
row_group_box_state.set_content_x(row_group_left_offset);
diff --git a/Userland/Libraries/LibWeb/Layout/VideoBox.cpp b/Userland/Libraries/LibWeb/Layout/VideoBox.cpp
index ae827f9526..ed2b2f79b2 100644
--- a/Userland/Libraries/LibWeb/Layout/VideoBox.cpp
+++ b/Userland/Libraries/LibWeb/Layout/VideoBox.cpp
@@ -38,10 +38,10 @@ HTML::HTMLVideoElement const& VideoBox::dom_node() const
void VideoBox::prepare_for_replaced_layout()
{
auto width = static_cast(dom_node().video_width());
- set_natural_width(width);
+ set_natural_width(CSSPixels(width));
auto height = static_cast(dom_node().video_height());
- set_natural_height(height);
+ set_natural_height(CSSPixels(height));
if (width != 0 && height != 0)
set_natural_aspect_ratio(width / height);
diff --git a/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp b/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp
index 764d72765e..7cb8b773c4 100644
--- a/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp
+++ b/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp
@@ -161,14 +161,14 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
double max_width_ratio = (background_positioning_area.width() / natural_image_width).to_double();
double max_height_ratio = (background_positioning_area.height() / natural_image_height).to_double();
double ratio = min(max_width_ratio, max_height_ratio);
- image_rect.set_size(natural_image_width * ratio, natural_image_height * ratio);
+ image_rect.set_size(natural_image_width.scaled(ratio), natural_image_height.scaled(ratio));
break;
}
case CSS::BackgroundSize::Cover: {
double max_width_ratio = (background_positioning_area.width() / natural_image_width).to_double();
double max_height_ratio = (background_positioning_area.height() / natural_image_height).to_double();
double ratio = max(max_width_ratio, max_height_ratio);
- image_rect.set_size(natural_image_width * ratio, natural_image_height * ratio);
+ image_rect.set_size(natural_image_width.scaled(ratio), natural_image_height.scaled(ratio));
break;
}
case CSS::BackgroundSize::LengthPercentage: {
@@ -263,7 +263,7 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
repeat_x = false;
} else {
auto space = fmod(background_positioning_area.width().to_double(), image_rect.width().to_double());
- x_step = image_rect.width() + (space / static_cast(whole_images - 1));
+ x_step = image_rect.width() + CSSPixels(space / static_cast(whole_images - 1));
repeat_x = true;
}
break;
@@ -294,7 +294,7 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
repeat_y = false;
} else {
auto space = fmod(background_positioning_area.height().to_float(), image_rect.height().to_float());
- y_step = image_rect.height() + (static_cast(space) / static_cast(whole_images - 1));
+ y_step = image_rect.height() + CSSPixels(static_cast(space) / static_cast(whole_images - 1));
repeat_y = true;
}
break;
diff --git a/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp b/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp
index 0a7999cafb..48a9377e91 100644
--- a/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp
+++ b/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp
@@ -117,7 +117,7 @@ LinearGradientData resolve_linear_gradient_data(Layout::NodeWithStyleAndBoxModel
auto resolved_color_stops = resolve_color_stop_positions(
node, linear_gradient.color_stop_list(), [&](auto const& length_percentage) {
- return length_percentage.to_px(node, gradient_length_px).to_float() / static_cast(gradient_length_px);
+ return length_percentage.to_px(node, CSSPixels(gradient_length_px)).to_float() / static_cast(gradient_length_px);
},
linear_gradient.is_repeating());
diff --git a/Userland/Libraries/LibWeb/Painting/MarkerPaintable.cpp b/Userland/Libraries/LibWeb/Painting/MarkerPaintable.cpp
index 14e0f1eee7..553c116007 100644
--- a/Userland/Libraries/LibWeb/Painting/MarkerPaintable.cpp
+++ b/Userland/Libraries/LibWeb/Painting/MarkerPaintable.cpp
@@ -39,7 +39,7 @@ void MarkerPaintable::paint(PaintContext& context, PaintPhase phase) const
CSSPixelRect enclosing = absolute_rect().to_rounded();
auto device_enclosing = context.enclosing_device_rect(enclosing);
- CSSPixels marker_width = enclosing.height() / 2.0;
+ CSSPixels marker_width = enclosing.height() / 2;
if (auto const* list_style_image = layout_box().list_style_image()) {
CSSPixelRect image_rect {
diff --git a/Userland/Libraries/LibWeb/Painting/PaintContext.cpp b/Userland/Libraries/LibWeb/Painting/PaintContext.cpp
index adfc89d907..df286a8d44 100644
--- a/Userland/Libraries/LibWeb/Painting/PaintContext.cpp
+++ b/Userland/Libraries/LibWeb/Painting/PaintContext.cpp
@@ -96,7 +96,7 @@ DevicePixelSize PaintContext::rounded_device_size(CSSPixelSize size) const
CSSPixels PaintContext::scale_to_css_pixels(DevicePixels device_pixels) const
{
- return device_pixels.value() / m_device_pixels_per_css_pixel;
+ return CSSPixels(device_pixels.value() / m_device_pixels_per_css_pixel);
}
CSSPixelPoint PaintContext::scale_to_css_point(DevicePixelPoint point) const
diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp
index 8c6d0891c2..98682a2448 100644
--- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp
+++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp
@@ -258,8 +258,8 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const
auto size_text_rect = border_rect;
size_text_rect.set_y(border_rect.y() + border_rect.height());
size_text_rect.set_top(size_text_rect.top());
- size_text_rect.set_width((float)font.width(size_text) + 4);
- size_text_rect.set_height(font.pixel_size() + 4);
+ size_text_rect.set_width(CSSPixels(font.width(size_text)) + 4);
+ size_text_rect.set_height(CSSPixels(font.pixel_size()) + 4);
auto size_text_device_rect = context.enclosing_device_rect(size_text_rect).to_type();
context.painter().fill_rect(size_text_device_rect, context.palette().color(Gfx::ColorRole::Tooltip));
context.painter().draw_rect(size_text_device_rect, context.palette().threed_shadow1());
@@ -503,7 +503,7 @@ static void paint_cursor_if_needed(PaintContext& context, Layout::TextNode const
auto fragment_rect = fragment.absolute_rect();
CSSPixelRect cursor_rect {
- fragment_rect.x() + text_node.font().width(fragment.text().substring_view(0, text_node.browsing_context().cursor_position().offset() - fragment.start())),
+ fragment_rect.x() + CSSPixels(text_node.font().width(fragment.text().substring_view(0, text_node.browsing_context().cursor_position().offset() - fragment.start()))),
fragment_rect.top(),
1,
fragment_rect.height()
@@ -518,7 +518,7 @@ static void paint_text_decoration(PaintContext& context, Gfx::Painter& painter,
{
auto& font = fragment.layout_node().font();
auto fragment_box = fragment.absolute_rect();
- CSSPixels glyph_height = font.pixel_size();
+ CSSPixels glyph_height = CSSPixels(font.pixel_size());
auto baseline = fragment_box.height() / 2 - (glyph_height + 4) / 2 + glyph_height;
auto line_color = text_node.computed_values().text_decoration_color();
@@ -526,9 +526,9 @@ static void paint_text_decoration(PaintContext& context, Gfx::Painter& painter,
CSSPixels css_line_thickness = [&] {
CSS::Length computed_thickness = text_node.computed_values().text_decoration_thickness().resolved(text_node, CSS::Length(1, CSS::Length::Type::Em));
if (computed_thickness.is_auto())
- return max(glyph_height * 0.1, 1.);
+ return max(glyph_height.scaled(0.1), 1);
- return computed_thickness.to_px(text_node).to_double();
+ return computed_thickness.to_px(text_node);
}();
auto device_line_thickness = context.rounded_device_pixels(css_line_thickness);
@@ -550,8 +550,8 @@ static void paint_text_decoration(PaintContext& context, Gfx::Painter& painter,
break;
case CSS::TextDecorationLine::LineThrough: {
auto x_height = font.x_height();
- line_start_point = context.rounded_device_point(fragment_box.top_left().translated(0, baseline - x_height * 0.5f));
- line_end_point = context.rounded_device_point(fragment_box.top_right().translated(-1, baseline - x_height * 0.5f));
+ line_start_point = context.rounded_device_point(fragment_box.top_left().translated(0, baseline - x_height * CSSPixels(0.5f)));
+ line_end_point = context.rounded_device_point(fragment_box.top_right().translated(-1, baseline - x_height * CSSPixels(0.5f)));
break;
}
case CSS::TextDecorationLine::Blink:
diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp
index 0f15fd0dcb..ec41ec7dfd 100644
--- a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp
+++ b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp
@@ -448,12 +448,12 @@ void StackingContext::paint(PaintContext& context) const
// to the size of the source (which could add some artefacts, though just scaling the bitmap already does that).
// We need to copy the background at the destination because a bunch of our rendering effects now rely on
// being able to sample the painter (see border radii, shadows, filters, etc).
- CSSPixelPoint destination_clipped_fixup {};
+ Gfx::FloatPoint destination_clipped_fixup {};
auto try_get_scaled_destination_bitmap = [&]() -> ErrorOr> {
Gfx::IntRect actual_destination_rect;
auto bitmap = TRY(context.painter().get_region_bitmap(destination_rect, Gfx::BitmapFormat::BGRA8888, actual_destination_rect));
// get_region_bitmap() may clip to a smaller region if the requested rect goes outside the painter, so we need to account for that.
- destination_clipped_fixup = CSSPixelPoint { destination_rect.location() - actual_destination_rect.location() };
+ destination_clipped_fixup = Gfx::FloatPoint { destination_rect.location() - actual_destination_rect.location() };
destination_rect = actual_destination_rect;
if (source_rect.size() != transformed_destination_rect.size()) {
auto sx = static_cast(source_rect.width()) / transformed_destination_rect.width();
@@ -469,7 +469,7 @@ void StackingContext::paint(PaintContext& context) const
return;
auto bitmap = bitmap_or_error.release_value_but_fixme_should_propagate_errors();
Gfx::Painter painter(bitmap);
- painter.translate(context.rounded_device_point(-paintable_box().absolute_paint_rect().location() + destination_clipped_fixup).to_type());
+ painter.translate(context.rounded_device_point(-paintable_box().absolute_paint_rect().location() + destination_clipped_fixup.to_type()).to_type());
auto paint_context = context.clone(painter);
paint_internal(paint_context);
diff --git a/Userland/Libraries/LibWeb/PixelUnits.h b/Userland/Libraries/LibWeb/PixelUnits.h
index b816660d30..a399976405 100644
--- a/Userland/Libraries/LibWeb/PixelUnits.h
+++ b/Userland/Libraries/LibWeb/PixelUnits.h
@@ -9,6 +9,7 @@
#pragma once
#include
+#include
#include
#include
#include
@@ -74,16 +75,16 @@ public:
m_value = static_cast(value) << fractional_bits;
}
- CSSPixels(float value)
- {
- if (!isnan(value))
- m_value = AK::clamp_to_int(value * fixed_point_denominator);
- }
-
- CSSPixels(double value)
+ template
+ explicit CSSPixels(F value)
{
if (!isnan(value))
m_value = AK::clamp_to_int(value * fixed_point_denominator);
+ // Note: The resolution of CSSPixels is 0.015625, so care must be taken when converting
+ // floats/doubles to CSSPixels as small values (such as scale factors) can underflow to zero,
+ // or otherwise produce inaccurate results (when scaled back up).
+ if (m_value == 0 && value != 0)
+ dbgln_if(LIBWEB_CSS_DEBUG, "CSSPixels: Conversion from float or double underflowed to zero");
}
template
@@ -217,6 +218,32 @@ public:
constexpr CSSPixels abs() const { return from_raw(::abs(m_value)); }
+ CSSPixels& scale_by(float value)
+ {
+ *this = CSSPixels(to_float() * value);
+ return *this;
+ }
+
+ CSSPixels& scale_by(double value)
+ {
+ *this = CSSPixels(to_double() * value);
+ return *this;
+ }
+
+ CSSPixels scaled(float value) const
+ {
+ auto result = *this;
+ result.scale_by(value);
+ return result;
+ }
+
+ CSSPixels scaled(double value) const
+ {
+ auto result = *this;
+ result.scale_by(value);
+ return result;
+ }
+
private:
i32 m_value { 0 };
};
diff --git a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp
index ce5e0fecb0..a11d88446e 100644
--- a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp
+++ b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp
@@ -227,7 +227,7 @@ Optional SVGGraphicsElement::stroke_width() const
viewport_height = svg_svg_layout_node->computed_values().height().to_px(*svg_svg_layout_node, 0);
}
}
- auto scaled_viewport_size = (viewport_width + viewport_height) * 0.5;
+ auto scaled_viewport_size = (viewport_width + viewport_height) * CSSPixels(0.5);
return width.to_px(*layout_node(), scaled_viewport_size).to_double();
}