Procházet zdrojové kódy

LibWeb: Add CSS `mask` property and make it form a stacking context

MacDue před 1 rokem
rodič
revize
dc58b5f418

+ 19 - 0
Userland/Libraries/LibWeb/CSS/ComputedValues.h

@@ -163,6 +163,21 @@ private:
     Variant<AK::URL, Color> m_value;
 };
 
+// https://drafts.fxtf.org/css-masking-1/#typedef-mask-reference
+class MaskReference {
+public:
+    // TODO: Support other mask types.
+    MaskReference(AK::URL const& url)
+        : m_url(url)
+    {
+    }
+
+    AK::URL const& url() const { return m_url; }
+
+private:
+    AK::URL m_url;
+};
+
 struct BackgroundLayerData {
     RefPtr<CSS::AbstractImageStyleValue const> background_image { nullptr };
     CSS::BackgroundAttachment attachment { CSS::BackgroundAttachment::Scroll };
@@ -344,6 +359,7 @@ public:
     Color stop_color() const { return m_noninherited.stop_color; }
     float stop_opacity() const { return m_noninherited.stop_opacity; }
     CSS::TextAnchor text_anchor() const { return m_inherited.text_anchor; }
+    Optional<MaskReference> const& mask() const { return m_noninherited.mask; }
 
     Vector<CSS::Transformation> const& transformations() const { return m_noninherited.transformations; }
     CSS::TransformOrigin const& transform_origin() const { return m_noninherited.transform_origin; }
@@ -488,6 +504,8 @@ protected:
         CSS::OutlineStyle outline_style { InitialValues::outline_style() };
         CSS::Length outline_width { InitialValues::outline_width() };
         CSS::TableLayout table_layout { InitialValues::table_layout() };
+
+        Optional<MaskReference> mask;
     } m_noninherited;
 };
 
@@ -605,6 +623,7 @@ public:
     void set_outline_offset(CSS::Length value) { m_noninherited.outline_offset = value; }
     void set_outline_style(CSS::OutlineStyle value) { m_noninherited.outline_style = value; }
     void set_outline_width(CSS::Length value) { m_noninherited.outline_width = value; }
+    void set_mask(MaskReference value) { m_noninherited.mask = value; }
 
     void set_math_shift(CSS::MathShift value) { m_inherited.math_shift = value; }
     void set_math_style(CSS::MathStyle value) { m_inherited.math_style = value; }

+ 13 - 0
Userland/Libraries/LibWeb/CSS/Properties.json

@@ -1484,6 +1484,19 @@
       "unitless-length"
     ]
   },
+  "mask": {
+    "affects-layout": false,
+    "affects-stacking-context": true,
+    "inherited": false,
+    "valid-identifiers": [
+      "none"
+    ],
+    "__comment": "FIXME: This should be a <mask-reference> and/or <mask-layer>#",
+    "valid-types": [
+      "url"
+    ],
+    "initial": "none"
+  },
   "math-depth": {
     "inherited": true,
     "initial": "0",

+ 13 - 0
Userland/Libraries/LibWeb/Layout/Node.cpp

@@ -184,6 +184,16 @@ bool Node::establishes_stacking_context() const
     if (!computed_values().backdrop_filter().is_none())
         return true;
 
+    // Element with any of the following properties with value other than none:
+    // - transform
+    // - filter
+    // - backdrop-filter
+    // - perspective
+    // - clip-path
+    // - mask / mask-image / mask-border
+    if (computed_values().mask().has_value())
+        return true;
+
     return computed_values().opacity() < 1.0f;
 }
 
@@ -755,6 +765,9 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
     else if (stroke_width->is_percentage())
         computed_values.set_stroke_width(CSS::LengthPercentage { stroke_width->as_percentage().percentage() });
 
+    if (auto mask = computed_style.property(CSS::PropertyID::Mask); mask->is_url())
+        computed_values.set_mask(mask->as_url().url());
+
     if (auto fill_rule = computed_style.fill_rule(); fill_rule.has_value())
         computed_values.set_fill_rule(*fill_rule);