ladybird/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h
Zac Brannelly 9165faca5e LibWeb: Support CSS property background-clip: text
From https://drafts.csswg.org/css-backgrounds-4/#background-clip
"The background is painted within (clipped to) the intersection of the
border box and the geometry of the text in the element and its in-flow
and floated descendants"

This change implements it in the following way:
1. Traverse the descendants of the element, collecting the Gfx::Path of
   glyphs into a vector.
2. The vector of collected paths is saved in the background painting
   command.
3. The painting commands executor uses the list of glyphs to paint a
   mask for background clipping.

Co-authored-by: Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
2024-03-03 15:33:12 +01:00

72 lines
2.6 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/CSS/Angle.h>
#include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h>
#include <LibWeb/Painting/GradientPainting.h>
namespace Web::CSS {
class ConicGradientStyleValue final : public AbstractImageStyleValue {
public:
static ValueComparingNonnullRefPtr<ConicGradientStyleValue> create(Angle from_angle, ValueComparingNonnullRefPtr<PositionStyleValue> position, Vector<AngularColorStopListElement> color_stop_list, GradientRepeating repeating)
{
VERIFY(color_stop_list.size() >= 2);
return adopt_ref(*new (nothrow) ConicGradientStyleValue(from_angle, move(position), move(color_stop_list), repeating));
}
virtual String to_string() const override;
void paint(PaintContext&, DevicePixelRect const& dest_rect, CSS::ImageRendering, Vector<Gfx::Path> const& clip_paths = {}) const override;
virtual bool equals(StyleValue const& other) const override;
Vector<AngularColorStopListElement> const& color_stop_list() const
{
return m_properties.color_stop_list;
}
float angle_degrees() const;
bool is_paintable() const override { return true; }
void resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize) const override;
virtual ~ConicGradientStyleValue() override = default;
bool is_repeating() const { return m_properties.repeating == GradientRepeating::Yes; }
private:
ConicGradientStyleValue(Angle from_angle, ValueComparingNonnullRefPtr<PositionStyleValue> position, Vector<AngularColorStopListElement> color_stop_list, GradientRepeating repeating)
: AbstractImageStyleValue(Type::ConicGradient)
, m_properties { .from_angle = from_angle, .position = move(position), .color_stop_list = move(color_stop_list), .repeating = repeating }
{
}
struct Properties {
// FIXME: Support <color-interpolation-method>
Angle from_angle;
ValueComparingNonnullRefPtr<PositionStyleValue> position;
Vector<AngularColorStopListElement> color_stop_list;
GradientRepeating repeating;
bool operator==(Properties const&) const = default;
} m_properties;
struct ResolvedData {
Painting::ConicGradientData data;
CSSPixelPoint position;
};
mutable Optional<ResolvedData> m_resolved;
};
}