diff options
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/ComputedValues.h | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/Document.cpp | 13 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/Document.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/Box.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/Node.cpp | 61 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/Node.h | 1 |
6 files changed, 86 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/ComputedValues.h b/Userland/Libraries/LibWeb/CSS/ComputedValues.h index a15f1cec15..b72172b2e1 100644 --- a/Userland/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Userland/Libraries/LibWeb/CSS/ComputedValues.h @@ -39,6 +39,12 @@ public: static float opacity() { return 1.0f; } }; +struct BackgroundLayerData { + RefPtr<CSS::ImageStyleValue> image; + CSS::Repeat repeat_x; + CSS::Repeat repeat_y; +}; + struct BorderData { public: Color color { Color::Transparent }; @@ -119,6 +125,7 @@ public: Color color() const { return m_inherited.color; } Color background_color() const { return m_noninherited.background_color; } + Vector<BackgroundLayerData> const& background_layers() const { return m_noninherited.background_layers; } BackgroundRepeatData background_repeat() const { return m_noninherited.background_repeat; } CSS::ListStyleType list_style_type() const { return m_inherited.list_style_type; } @@ -176,6 +183,7 @@ protected: Length border_top_left_radius; Length border_top_right_radius; Color background_color { InitialValues::background_color() }; + Vector<BackgroundLayerData> background_layers; BackgroundRepeatData background_repeat { InitialValues::background_repeat(), InitialValues::background_repeat() }; CSS::FlexDirection flex_direction { InitialValues::flex_direction() }; CSS::FlexWrap flex_wrap { InitialValues::flex_wrap() }; @@ -203,6 +211,7 @@ public: void set_pointer_events(CSS::PointerEvents value) { m_inherited.pointer_events = value; } void set_background_color(const Color& color) { m_noninherited.background_color = color; } void set_background_repeat(BackgroundRepeatData repeat) { m_noninherited.background_repeat = repeat; } + void set_background_layers(Vector<BackgroundLayerData>&& layers) { m_noninherited.background_layers = move(layers); } void set_float(CSS::Float value) { m_noninherited.float_ = value; } void set_clear(CSS::Clear value) { m_noninherited.clear = value; } void set_z_index(Optional<int> value) { m_noninherited.z_index = value; } diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 8c78d203b4..911555367d 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -353,6 +353,19 @@ Color Document::background_color(const Palette& palette) const return color; } +Vector<CSS::BackgroundLayerData> const* Document::background_layers() const +{ + auto* body_element = body(); + if (!body_element) + return {}; + + auto* body_layout_node = body_element->layout_node(); + if (!body_layout_node) + return {}; + + return &body_layout_node->background_layers(); +} + RefPtr<Gfx::Bitmap> Document::background_image() const { auto* body_element = body(); diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index 98c65e68b9..cf3c809cea 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -130,6 +130,7 @@ public: const Page* page() const; Color background_color(const Gfx::Palette&) const; + Vector<CSS::BackgroundLayerData> const* background_layers() const; RefPtr<Gfx::Bitmap> background_image() const; CSS::Repeat background_repeat_x() const; CSS::Repeat background_repeat_y() const; diff --git a/Userland/Libraries/LibWeb/Layout/Box.cpp b/Userland/Libraries/LibWeb/Layout/Box.cpp index cc452d6b7e..f66a757b15 100644 --- a/Userland/Libraries/LibWeb/Layout/Box.cpp +++ b/Userland/Libraries/LibWeb/Layout/Box.cpp @@ -72,6 +72,7 @@ void Box::paint_background(PaintContext& context) Gfx::IntRect background_rect; Color background_color = computed_values().background_color(); + auto* background_layers = &computed_values().background_layers(); const Gfx::Bitmap* background_image = this->background_image() ? this->background_image()->bitmap() : nullptr; CSS::BackgroundRepeatData background_repeat = computed_values().background_repeat(); @@ -82,6 +83,7 @@ void Box::paint_background(PaintContext& context) // Section 2.11.2: If the computed value of background-image on the root element is none and its background-color is transparent, // user agents must instead propagate the computed values of the background properties from that element’s first HTML BODY child element. if (document().html_element()->should_use_body_background_properties()) { + background_layers = document().background_layers(); background_color = document().background_color(context.palette()); background_image = document().background_image(); background_repeat = { document().background_repeat_x(), document().background_repeat_y() }; diff --git a/Userland/Libraries/LibWeb/Layout/Node.cpp b/Userland/Libraries/LibWeb/Layout/Node.cpp index a855d068ea..82973509cf 100644 --- a/Userland/Libraries/LibWeb/Layout/Node.cpp +++ b/Userland/Libraries/LibWeb/Layout/Node.cpp @@ -215,6 +215,66 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style) m_font_size = default_font_size; } + { + auto attachments = specified_style.property(CSS::PropertyID::BackgroundAttachment); + auto clips = specified_style.property(CSS::PropertyID::BackgroundClip); + auto images = specified_style.property(CSS::PropertyID::BackgroundImage); + auto origins = specified_style.property(CSS::PropertyID::BackgroundOrigin); + auto positions = specified_style.property(CSS::PropertyID::BackgroundPosition); + auto repeats = specified_style.property(CSS::PropertyID::BackgroundRepeat); + auto sizes = specified_style.property(CSS::PropertyID::BackgroundSize); + + auto count_layers = [](auto maybe_style_value) -> size_t { + if (maybe_style_value.has_value() && maybe_style_value.value()->is_value_list()) + return maybe_style_value.value()->as_value_list().size(); + else + return 1; + }; + + auto value_for_layer = [](auto maybe_style_value, size_t layer_index) -> RefPtr<CSS::StyleValue> { + if (!maybe_style_value.has_value()) + return nullptr; + auto& style_value = maybe_style_value.value(); + if (style_value->is_value_list()) + return style_value->as_value_list().value_at(layer_index, true); + return style_value; + }; + + size_t layer_count = 1; + layer_count = max(layer_count, count_layers(attachments)); + layer_count = max(layer_count, count_layers(clips)); + layer_count = max(layer_count, count_layers(images)); + layer_count = max(layer_count, count_layers(origins)); + layer_count = max(layer_count, count_layers(positions)); + layer_count = max(layer_count, count_layers(repeats)); + layer_count = max(layer_count, count_layers(sizes)); + + Vector<CSS::BackgroundLayerData> layers; + layers.ensure_capacity(layer_count); + + for (size_t layer_index = 0; layer_index < layer_count; layer_index++) { + CSS::BackgroundLayerData layer; + + // TODO: Other properties + + if (auto image_value = value_for_layer(images, layer_index); image_value && image_value->is_image()) { + layer.image = image_value->as_image(); + layer.image->load_bitmap(document()); + } + + if (auto repeat_value = value_for_layer(repeats, layer_index); repeat_value && repeat_value->is_background_repeat()) { + layer.repeat_x = repeat_value->as_background_repeat().repeat_x(); + layer.repeat_y = repeat_value->as_background_repeat().repeat_y(); + } + + layers.append(move(layer)); + } + + computed_values.set_background_layers(move(layers)); + } + computed_values.set_background_color(specified_style.color_or_fallback(CSS::PropertyID::BackgroundColor, *this, CSS::InitialValues::background_color())); + + // FIXME: Remove this auto bgimage = specified_style.property(CSS::PropertyID::BackgroundImage); if (bgimage.has_value() && bgimage.value()->is_image()) { m_background_image = bgimage.value()->as_image(); @@ -323,7 +383,6 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style) } computed_values.set_color(specified_style.color_or_fallback(CSS::PropertyID::Color, *this, CSS::InitialValues::color())); - computed_values.set_background_color(specified_style.color_or_fallback(CSS::PropertyID::BackgroundColor, *this, CSS::InitialValues::background_color())); computed_values.set_z_index(specified_style.z_index()); computed_values.set_opacity(specified_style.opacity()); diff --git a/Userland/Libraries/LibWeb/Layout/Node.h b/Userland/Libraries/LibWeb/Layout/Node.h index 0215ecff36..1ff7d430b9 100644 --- a/Userland/Libraries/LibWeb/Layout/Node.h +++ b/Userland/Libraries/LibWeb/Layout/Node.h @@ -206,6 +206,7 @@ public: float line_height() const { return m_line_height; } float font_size() const { return m_font_size; } const CSS::ImageStyleValue* background_image() const { return m_background_image; } + Vector<CSS::BackgroundLayerData> const& background_layers() const { return computed_values().background_layers(); } const CSS::ImageStyleValue* list_style_image() const { return m_list_style_image; } NonnullRefPtr<NodeWithStyle> create_anonymous_wrapper() const; |