Преглед изворни кода

LibWeb: Add support for the lh and rlh length units

Resolving these units is somewhat tricky because of their interaction
with both font-size and line-height, but this implementation seems to
work as tested in http://wpt.live/css/css-values/lh-unit-001.html and
http://wpt.live/css/css-values/lh-unit-002.html
Simon Wanner пре 2 година
родитељ
комит
554c4af90f

+ 14 - 2
Userland/Libraries/LibWeb/CSS/Length.cpp

@@ -70,7 +70,7 @@ Length Length::resolved(Layout::Node const& layout_node) const
     return *this;
     return *this;
 }
 }
 
 
-CSSPixels Length::relative_length_to_px(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size) const
+CSSPixels Length::relative_length_to_px(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height) const
 {
 {
     switch (m_type) {
     switch (m_type) {
     case Type::Ex:
     case Type::Ex:
@@ -90,6 +90,10 @@ CSSPixels Length::relative_length_to_px(CSSPixelRect const& viewport_rect, Gfx::
         return min(viewport_rect.width(), viewport_rect.height()) * (m_value / 100);
         return min(viewport_rect.width(), viewport_rect.height()) * (m_value / 100);
     case Type::Vmax:
     case Type::Vmax:
         return max(viewport_rect.width(), viewport_rect.height()) * (m_value / 100);
         return max(viewport_rect.width(), viewport_rect.height()) * (m_value / 100);
+    case Type::Lh:
+        return m_value * line_height;
+    case Type::Rlh:
+        return m_value * root_line_height;
     default:
     default:
         VERIFY_NOT_REACHED();
         VERIFY_NOT_REACHED();
     }
     }
@@ -109,7 +113,7 @@ CSSPixels Length::to_px(Layout::Node const& layout_node) const
     auto* root_element = layout_node.document().document_element();
     auto* root_element = layout_node.document().document_element();
     if (!root_element || !root_element->layout_node())
     if (!root_element || !root_element->layout_node())
         return 0;
         return 0;
-    return to_px(viewport_rect, layout_node.font().pixel_metrics(), layout_node.computed_values().font_size(), root_element->layout_node()->computed_values().font_size());
+    return to_px(viewport_rect, layout_node.font().pixel_metrics(), layout_node.computed_values().font_size(), root_element->layout_node()->computed_values().font_size(), layout_node.line_height(), root_element->layout_node()->line_height());
 }
 }
 
 
 ErrorOr<String> Length::to_string() const
 ErrorOr<String> Length::to_string() const
@@ -156,6 +160,10 @@ char const* Length::unit_name() const
         return "vmax";
         return "vmax";
     case Type::Vmin:
     case Type::Vmin:
         return "vmin";
         return "vmin";
+    case Type::Lh:
+        return "lh";
+    case Type::Rlh:
+        return "rlh";
     case Type::Calculated:
     case Type::Calculated:
         return "calculated";
         return "calculated";
     }
     }
@@ -194,6 +202,10 @@ Optional<Length::Type> Length::unit_from_name(StringView name)
         return Length::Type::In;
         return Length::Type::In;
     } else if (name.equals_ignoring_ascii_case("Q"sv)) {
     } else if (name.equals_ignoring_ascii_case("Q"sv)) {
         return Length::Type::Q;
         return Length::Type::Q;
+    } else if (name.equals_ignoring_ascii_case("lh"sv)) {
+        return Length::Type::Lh;
+    } else if (name.equals_ignoring_ascii_case("rlh"sv)) {
+        return Length::Type::Rlh;
     }
     }
 
 
     return {};
     return {};

+ 8 - 4
Userland/Libraries/LibWeb/CSS/Length.h

@@ -35,6 +35,8 @@ public:
         Vw,
         Vw,
         Vmax,
         Vmax,
         Vmin,
         Vmin,
+        Lh,
+        Rlh,
     };
     };
 
 
     static Optional<Type> unit_from_name(StringView);
     static Optional<Type> unit_from_name(StringView);
@@ -76,7 +78,9 @@ public:
             || m_type == Type::Vh
             || m_type == Type::Vh
             || m_type == Type::Vw
             || m_type == Type::Vw
             || m_type == Type::Vmax
             || m_type == Type::Vmax
-            || m_type == Type::Vmin;
+            || m_type == Type::Vmin
+            || m_type == Type::Lh
+            || m_type == Type::Rlh;
     }
     }
 
 
     float raw_value() const { return m_value; }
     float raw_value() const { return m_value; }
@@ -84,12 +88,12 @@ public:
 
 
     CSSPixels to_px(Layout::Node const&) const;
     CSSPixels to_px(Layout::Node const&) const;
 
 
-    ALWAYS_INLINE CSSPixels to_px(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size) const
+    ALWAYS_INLINE CSSPixels to_px(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height) const
     {
     {
         if (is_auto())
         if (is_auto())
             return 0;
             return 0;
         if (is_relative())
         if (is_relative())
-            return relative_length_to_px(viewport_rect, font_metrics, font_size, root_font_size);
+            return relative_length_to_px(viewport_rect, font_metrics, font_size, root_font_size, line_height, root_line_height);
         if (is_calculated())
         if (is_calculated())
             VERIFY_NOT_REACHED(); // We can't resolve a calculated length from here. :^(
             VERIFY_NOT_REACHED(); // We can't resolve a calculated length from here. :^(
         return absolute_length_to_px();
         return absolute_length_to_px();
@@ -125,7 +129,7 @@ public:
     // this file already. To break the cyclic dependency, we must move all method definitions out.
     // this file already. To break the cyclic dependency, we must move all method definitions out.
     bool operator==(Length const& other) const;
     bool operator==(Length const& other) const;
 
 
-    CSSPixels relative_length_to_px(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size) const;
+    CSSPixels relative_length_to_px(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height) const;
 
 
 private:
 private:
     char const* unit_name() const;
     char const* unit_name() const;

+ 3 - 2
Userland/Libraries/LibWeb/CSS/MediaQuery.cpp

@@ -168,9 +168,10 @@ bool MediaFeature::compare(HTML::Window const& window, MediaFeatureValue left, C
             auto const& initial_font = window.associated_document().style_computer().initial_font();
             auto const& initial_font = window.associated_document().style_computer().initial_font();
             Gfx::FontPixelMetrics const& initial_font_metrics = initial_font.pixel_metrics();
             Gfx::FontPixelMetrics const& initial_font_metrics = initial_font.pixel_metrics();
             float initial_font_size = initial_font.presentation_size();
             float initial_font_size = initial_font.presentation_size();
+            float initial_line_height = initial_font_metrics.line_spacing();
 
 
-            left_px = left.length().to_px(viewport_rect, initial_font_metrics, initial_font_size, initial_font_size);
-            right_px = right.length().to_px(viewport_rect, initial_font_metrics, initial_font_size, initial_font_size);
+            left_px = left.length().to_px(viewport_rect, initial_font_metrics, initial_font_size, initial_font_size, initial_line_height, initial_line_height);
+            right_px = right.length().to_px(viewport_rect, initial_font_metrics, initial_font_size, initial_font_size, initial_line_height, initial_line_height);
         }
         }
 
 
         switch (comparison) {
         switch (comparison) {

+ 54 - 6
Userland/Libraries/LibWeb/CSS/StyleComputer.cpp

@@ -1010,7 +1010,27 @@ CSSPixels StyleComputer::root_element_font_size() const
 
 
     auto root_value = computed_root_style->property(CSS::PropertyID::FontSize);
     auto root_value = computed_root_style->property(CSS::PropertyID::FontSize);
 
 
-    return root_value->to_length().to_px(viewport_rect(), computed_root_style->computed_font().pixel_metrics(), default_root_element_font_size, default_root_element_font_size);
+    auto font_metrics = computed_root_style->computed_font().pixel_metrics();
+    auto line_height = font_metrics.line_spacing();
+    return root_value->to_length().to_px(viewport_rect(), font_metrics, default_root_element_font_size, default_root_element_font_size, line_height, line_height);
+}
+
+CSSPixels StyleComputer::root_element_line_height() const
+{
+    constexpr float default_root_element_line_height = 16;
+
+    auto const* root_element = m_document->first_child_of_type<HTML::HTMLHtmlElement>();
+    if (!root_element)
+        return default_root_element_line_height;
+
+    auto const* computed_root_style = root_element->computed_css_values();
+    if (!computed_root_style)
+        return default_root_element_line_height;
+
+    auto font_metrics = computed_root_style->computed_font().pixel_metrics();
+    auto font_size = root_element_font_size();
+    auto line_height = font_metrics.line_spacing();
+    return computed_root_style->line_height(viewport_rect(), font_metrics, font_size, font_size, line_height, line_height);
 }
 }
 
 
 void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element) const
 void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element) const
@@ -1022,6 +1042,7 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
     compute_defaulted_property_value(style, element, CSS::PropertyID::FontStretch, pseudo_element);
     compute_defaulted_property_value(style, element, CSS::PropertyID::FontStretch, pseudo_element);
     compute_defaulted_property_value(style, element, CSS::PropertyID::FontStyle, pseudo_element);
     compute_defaulted_property_value(style, element, CSS::PropertyID::FontStyle, pseudo_element);
     compute_defaulted_property_value(style, element, CSS::PropertyID::FontWeight, pseudo_element);
     compute_defaulted_property_value(style, element, CSS::PropertyID::FontWeight, pseudo_element);
+    compute_defaulted_property_value(style, element, CSS::PropertyID::LineHeight, pseudo_element);
 
 
     auto* parent_element = element_to_inherit_style_from(element, pseudo_element);
     auto* parent_element = element_to_inherit_style_from(element, pseudo_element);
 
 
@@ -1156,6 +1177,7 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
 
 
     } else {
     } else {
         auto root_font_size = root_element_font_size();
         auto root_font_size = root_element_font_size();
+        auto root_line_height = root_element_line_height();
 
 
         Gfx::FontPixelMetrics font_metrics;
         Gfx::FontPixelMetrics font_metrics;
         if (parent_element && parent_element->computed_css_values())
         if (parent_element && parent_element->computed_css_values())
@@ -1169,8 +1191,9 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
             auto value = parent_element->computed_css_values()->property(CSS::PropertyID::FontSize);
             auto value = parent_element->computed_css_values()->property(CSS::PropertyID::FontSize);
             if (value->is_length()) {
             if (value->is_length()) {
                 auto length = static_cast<LengthStyleValue const&>(*value).to_length();
                 auto length = static_cast<LengthStyleValue const&>(*value).to_length();
+                auto parent_line_height = parent_or_root_element_line_height(parent_element, {});
                 if (length.is_absolute() || length.is_relative())
                 if (length.is_absolute() || length.is_relative())
-                    return length.to_px(viewport_rect(), font_metrics, font_size_in_px, root_font_size);
+                    return length.to_px(viewport_rect(), font_metrics, font_size_in_px, root_font_size, parent_line_height, root_line_height);
             }
             }
             return font_size_in_px;
             return font_size_in_px;
         };
         };
@@ -1190,7 +1213,8 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
             // FIXME: Support font-size: calc(...)
             // FIXME: Support font-size: calc(...)
             //        Theoretically we can do this now, but to resolve it we need a layout_node which we might not have. :^(
             //        Theoretically we can do this now, but to resolve it we need a layout_node which we might not have. :^(
             if (!maybe_length->is_calculated()) {
             if (!maybe_length->is_calculated()) {
-                auto px = maybe_length.value().to_px(viewport_rect(), font_metrics, parent_font_size(), root_font_size).value();
+                auto parent_line_height = parent_or_root_element_line_height(element, pseudo_element);
+                auto px = maybe_length.value().to_px(viewport_rect(), font_metrics, parent_font_size(), root_font_size, parent_line_height, root_line_height).value();
                 if (px != 0)
                 if (px != 0)
                     font_size_in_px = px;
                     font_size_in_px = px;
             }
             }
@@ -1311,11 +1335,29 @@ Gfx::Font const& StyleComputer::initial_font() const
     return StyleProperties::font_fallback(false, false);
     return StyleProperties::font_fallback(false, false);
 }
 }
 
 
-void StyleComputer::absolutize_values(StyleProperties& style, DOM::Element const*, Optional<CSS::Selector::PseudoElement>) const
+CSSPixels StyleComputer::parent_or_root_element_line_height(DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element) const
 {
 {
+    auto* parent_element = element_to_inherit_style_from(element, pseudo_element);
+    if (!parent_element)
+        return root_element_line_height();
+    auto root_font_size = root_element_font_size();
+    auto root_line_height = root_element_line_height();
+    auto* computed_values = parent_element->computed_css_values();
+    auto parent_font_size = computed_values->property(CSS::PropertyID::FontSize)->to_length();
+    // FIXME: Can the parent font size be non-absolute here?
+    auto parent_font_size_value = parent_font_size.is_absolute() ? parent_font_size.absolute_length_to_px() : root_font_size;
+    auto parent_parent_line_height = parent_or_root_element_line_height(parent_element, {});
+    return computed_values->line_height(viewport_rect(), computed_values->computed_font().pixel_metrics(), parent_font_size_value, root_font_size, parent_parent_line_height, root_line_height);
+}
+
+void StyleComputer::absolutize_values(StyleProperties& style, DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element) const
+{
+    auto root_line_height = root_element_line_height();
+    auto parent_or_root_line_height = parent_or_root_element_line_height(element, pseudo_element);
+
     auto font_metrics = style.computed_font().pixel_metrics();
     auto font_metrics = style.computed_font().pixel_metrics();
     auto root_font_size = root_element_font_size();
     auto root_font_size = root_element_font_size();
-    auto font_size = style.property(CSS::PropertyID::FontSize)->to_length().to_px(viewport_rect(), font_metrics, root_font_size, root_font_size);
+    auto font_size = style.property(CSS::PropertyID::FontSize)->to_length().to_px(viewport_rect(), font_metrics, root_font_size, root_font_size, parent_or_root_line_height, root_line_height);
 
 
     // NOTE: Percentage line-height values are relative to the font-size of the element.
     // NOTE: Percentage line-height values are relative to the font-size of the element.
     //       We have to resolve them right away, so that the *computed* line-height is ready for inheritance.
     //       We have to resolve them right away, so that the *computed* line-height is ready for inheritance.
@@ -1327,11 +1369,17 @@ void StyleComputer::absolutize_values(StyleProperties& style, DOM::Element const
             Length::make_px(font_size * line_height_value_slot->as_percentage().percentage().as_fraction()));
             Length::make_px(font_size * line_height_value_slot->as_percentage().percentage().as_fraction()));
     }
     }
 
 
+    auto line_height = style.line_height(viewport_rect(), font_metrics, font_size.value(), root_font_size.value(), parent_or_root_line_height, root_line_height);
+
+    // NOTE: line-height might be using lh which should be resolved against the parent line height (like we did here already)
+    if (line_height_value_slot && line_height_value_slot->is_length())
+        line_height_value_slot = LengthStyleValue::create(Length::make_px(line_height));
+
     for (size_t i = 0; i < style.m_property_values.size(); ++i) {
     for (size_t i = 0; i < style.m_property_values.size(); ++i) {
         auto& value_slot = style.m_property_values[i];
         auto& value_slot = style.m_property_values[i];
         if (!value_slot)
         if (!value_slot)
             continue;
             continue;
-        value_slot = value_slot->absolutized(viewport_rect(), font_metrics, font_size.value(), root_font_size.value());
+        value_slot = value_slot->absolutized(viewport_rect(), font_metrics, font_size.value(), root_font_size.value(), line_height, root_line_height);
     }
     }
 }
 }
 
 

+ 2 - 0
Userland/Libraries/LibWeb/CSS/StyleComputer.h

@@ -103,6 +103,8 @@ private:
 
 
     CSSPixelRect viewport_rect() const;
     CSSPixelRect viewport_rect() const;
     CSSPixels root_element_font_size() const;
     CSSPixels root_element_font_size() const;
+    CSSPixels root_element_line_height() const;
+    CSSPixels parent_or_root_element_line_height(DOM::Element const*, Optional<CSS::Selector::PseudoElement>) const;
 
 
     struct MatchingRuleSet {
     struct MatchingRuleSet {
         Vector<MatchingRule> user_agent_rules;
         Vector<MatchingRule> user_agent_rules;

+ 29 - 0
Userland/Libraries/LibWeb/CSS/StyleProperties.cpp

@@ -138,6 +138,35 @@ NonnullRefPtr<Gfx::Font const> StyleProperties::font_fallback(bool monospace, bo
     return Platform::FontPlugin::the().default_font();
     return Platform::FontPlugin::the().default_font();
 }
 }
 
 
+// FIXME: This implementation is almost identical to line_height(Layout::Node) below. Maybe they can be combined somehow.
+CSSPixels StyleProperties::line_height(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels parent_line_height, CSSPixels root_line_height) const
+{
+    auto line_height = property(CSS::PropertyID::LineHeight);
+
+    if (line_height->is_identifier() && line_height->to_identifier() == ValueID::Normal)
+        return font_metrics.line_spacing();
+
+    if (line_height->is_length()) {
+        auto line_height_length = line_height->to_length();
+        if (!line_height_length.is_auto())
+            return line_height_length.to_px(viewport_rect, font_metrics, font_size, root_font_size, parent_line_height, root_line_height);
+    }
+
+    if (line_height->is_numeric())
+        return Length(line_height->to_number(), Length::Type::Em).to_px(viewport_rect, font_metrics, font_size, root_font_size, parent_line_height, root_line_height);
+
+    if (line_height->is_percentage()) {
+        // Percentages are relative to 1em. https://www.w3.org/TR/css-inline-3/#valdef-line-height-percentage
+        auto& percentage = line_height->as_percentage().percentage();
+        return Length(percentage.as_fraction(), Length::Type::Em).to_px(viewport_rect, font_metrics, font_size, root_font_size, parent_line_height, root_line_height);
+    }
+
+    if (line_height->is_calculated())
+        return CSS::Length::make_calculated(const_cast<CalculatedStyleValue&>(line_height->as_calculated())).to_px(viewport_rect, font_metrics, font_size, root_font_size, parent_line_height, root_line_height);
+
+    return font_metrics.line_spacing();
+}
+
 CSSPixels StyleProperties::line_height(Layout::Node const& layout_node) const
 CSSPixels StyleProperties::line_height(Layout::Node const& layout_node) const
 {
 {
     auto line_height = property(CSS::PropertyID::LineHeight);
     auto line_height = property(CSS::PropertyID::LineHeight);

+ 1 - 0
Userland/Libraries/LibWeb/CSS/StyleProperties.h

@@ -108,6 +108,7 @@ public:
         m_font = move(font);
         m_font = move(font);
     }
     }
 
 
+    CSSPixels line_height(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const&, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height) const;
     CSSPixels line_height(Layout::Node const&) const;
     CSSPixels line_height(Layout::Node const&) const;
 
 
     bool operator==(StyleProperties const&) const;
     bool operator==(StyleProperties const&) const;

+ 13 - 13
Userland/Libraries/LibWeb/CSS/StyleValue.cpp

@@ -2235,48 +2235,48 @@ ValueComparingNonnullRefPtr<LengthStyleValue> LengthStyleValue::create(Length co
     return adopt_ref(*new LengthStyleValue(length));
     return adopt_ref(*new LengthStyleValue(length));
 }
 }
 
 
-static Optional<CSS::Length> absolutized_length(CSS::Length const& length, CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size)
+static Optional<CSS::Length> absolutized_length(CSS::Length const& length, CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height)
 {
 {
     if (length.is_px())
     if (length.is_px())
         return {};
         return {};
     if (length.is_absolute() || length.is_relative()) {
     if (length.is_absolute() || length.is_relative()) {
-        auto px = length.to_px(viewport_rect, font_metrics, font_size, root_font_size);
+        auto px = length.to_px(viewport_rect, font_metrics, font_size, root_font_size, line_height, root_line_height);
         return CSS::Length::make_px(px);
         return CSS::Length::make_px(px);
     }
     }
     return {};
     return {};
 }
 }
 
 
-ValueComparingNonnullRefPtr<StyleValue const> StyleValue::absolutized(CSSPixelRect const&, Gfx::FontPixelMetrics const&, CSSPixels, CSSPixels) const
+ValueComparingNonnullRefPtr<StyleValue const> StyleValue::absolutized(CSSPixelRect const&, Gfx::FontPixelMetrics const&, CSSPixels, CSSPixels, CSSPixels, CSSPixels) const
 {
 {
     return *this;
     return *this;
 }
 }
 
 
-ValueComparingNonnullRefPtr<StyleValue const> LengthStyleValue::absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size) const
+ValueComparingNonnullRefPtr<StyleValue const> LengthStyleValue::absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height) const
 {
 {
-    if (auto length = absolutized_length(m_length, viewport_rect, font_metrics, font_size, root_font_size); length.has_value())
+    if (auto length = absolutized_length(m_length, viewport_rect, font_metrics, font_size, root_font_size, line_height, root_line_height); length.has_value())
         return LengthStyleValue::create(length.release_value());
         return LengthStyleValue::create(length.release_value());
     return *this;
     return *this;
 }
 }
 
 
-ValueComparingNonnullRefPtr<StyleValue const> ShadowStyleValue::absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size) const
+ValueComparingNonnullRefPtr<StyleValue const> ShadowStyleValue::absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height) const
 {
 {
-    auto absolutized_offset_x = absolutized_length(m_properties.offset_x, viewport_rect, font_metrics, font_size, root_font_size).value_or(m_properties.offset_x);
-    auto absolutized_offset_y = absolutized_length(m_properties.offset_y, viewport_rect, font_metrics, font_size, root_font_size).value_or(m_properties.offset_y);
-    auto absolutized_blur_radius = absolutized_length(m_properties.blur_radius, viewport_rect, font_metrics, font_size, root_font_size).value_or(m_properties.blur_radius);
-    auto absolutized_spread_distance = absolutized_length(m_properties.spread_distance, viewport_rect, font_metrics, font_size, root_font_size).value_or(m_properties.spread_distance);
+    auto absolutized_offset_x = absolutized_length(m_properties.offset_x, viewport_rect, font_metrics, font_size, root_font_size, line_height, root_line_height).value_or(m_properties.offset_x);
+    auto absolutized_offset_y = absolutized_length(m_properties.offset_y, viewport_rect, font_metrics, font_size, root_font_size, line_height, root_line_height).value_or(m_properties.offset_y);
+    auto absolutized_blur_radius = absolutized_length(m_properties.blur_radius, viewport_rect, font_metrics, font_size, root_font_size, line_height, root_line_height).value_or(m_properties.blur_radius);
+    auto absolutized_spread_distance = absolutized_length(m_properties.spread_distance, viewport_rect, font_metrics, font_size, root_font_size, line_height, root_line_height).value_or(m_properties.spread_distance);
     return ShadowStyleValue::create(m_properties.color, absolutized_offset_x, absolutized_offset_y, absolutized_blur_radius, absolutized_spread_distance, m_properties.placement);
     return ShadowStyleValue::create(m_properties.color, absolutized_offset_x, absolutized_offset_y, absolutized_blur_radius, absolutized_spread_distance, m_properties.placement);
 }
 }
 
 
-ValueComparingNonnullRefPtr<StyleValue const> BorderRadiusStyleValue::absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size) const
+ValueComparingNonnullRefPtr<StyleValue const> BorderRadiusStyleValue::absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height) const
 {
 {
     if (m_properties.horizontal_radius.is_percentage() && m_properties.vertical_radius.is_percentage())
     if (m_properties.horizontal_radius.is_percentage() && m_properties.vertical_radius.is_percentage())
         return *this;
         return *this;
     auto absolutized_horizontal_radius = m_properties.horizontal_radius;
     auto absolutized_horizontal_radius = m_properties.horizontal_radius;
     auto absolutized_vertical_radius = m_properties.vertical_radius;
     auto absolutized_vertical_radius = m_properties.vertical_radius;
     if (!m_properties.horizontal_radius.is_percentage())
     if (!m_properties.horizontal_radius.is_percentage())
-        absolutized_horizontal_radius = absolutized_length(m_properties.horizontal_radius.length(), viewport_rect, font_metrics, font_size, root_font_size).value_or(m_properties.horizontal_radius.length());
+        absolutized_horizontal_radius = absolutized_length(m_properties.horizontal_radius.length(), viewport_rect, font_metrics, font_size, root_font_size, line_height, root_line_height).value_or(m_properties.horizontal_radius.length());
     if (!m_properties.vertical_radius.is_percentage())
     if (!m_properties.vertical_radius.is_percentage())
-        absolutized_vertical_radius = absolutized_length(m_properties.vertical_radius.length(), viewport_rect, font_metrics, font_size, root_font_size).value_or(m_properties.vertical_radius.length());
+        absolutized_vertical_radius = absolutized_length(m_properties.vertical_radius.length(), viewport_rect, font_metrics, font_size, root_font_size, line_height, root_line_height).value_or(m_properties.vertical_radius.length());
     return BorderRadiusStyleValue::create(absolutized_horizontal_radius, absolutized_vertical_radius);
     return BorderRadiusStyleValue::create(absolutized_horizontal_radius, absolutized_vertical_radius);
 }
 }
 
 

+ 4 - 4
Userland/Libraries/LibWeb/CSS/StyleValue.h

@@ -465,7 +465,7 @@ public:
     virtual bool has_number() const { return false; }
     virtual bool has_number() const { return false; }
     virtual bool has_integer() const { return false; }
     virtual bool has_integer() const { return false; }
 
 
-    virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size) const;
+    virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height) const;
 
 
     virtual Color to_color(Layout::NodeWithStyle const&) const { return {}; }
     virtual Color to_color(Layout::NodeWithStyle const&) const { return {}; }
     virtual EdgeRect to_rect() const { VERIFY_NOT_REACHED(); }
     virtual EdgeRect to_rect() const { VERIFY_NOT_REACHED(); }
@@ -701,7 +701,7 @@ private:
     {
     {
     }
     }
 
 
-    virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size) const override;
+    virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height) const override;
 
 
     struct Properties {
     struct Properties {
         bool is_elliptical;
         bool is_elliptical;
@@ -1631,7 +1631,7 @@ public:
     virtual ErrorOr<String> to_string() const override { return m_length.to_string(); }
     virtual ErrorOr<String> to_string() const override { return m_length.to_string(); }
     virtual Length to_length() const override { return m_length; }
     virtual Length to_length() const override { return m_length; }
     virtual ValueID to_identifier() const override { return has_auto() ? ValueID::Auto : ValueID::Invalid; }
     virtual ValueID to_identifier() const override { return has_auto() ? ValueID::Auto : ValueID::Invalid; }
-    virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size) const override;
+    virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height) const override;
 
 
     bool properties_equal(LengthStyleValue const& other) const { return m_length == other.m_length; }
     bool properties_equal(LengthStyleValue const& other) const { return m_length == other.m_length; }
 
 
@@ -1860,7 +1860,7 @@ private:
     {
     {
     }
     }
 
 
-    virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size) const override;
+    virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height) const override;
 
 
     struct Properties {
     struct Properties {
         Color color;
         Color color;