LibWeb/CSS: Implement mix-blend-mode

This adds support for the `mix-blend-mode` CSS property.
This commit is contained in:
Glenn Skrzypczak 2025-01-22 09:50:49 +01:00 committed by Sam Atkins
commit 0fe30886f5
Notes: github-actions[bot] 2025-02-05 11:28:01 +00:00
24 changed files with 311 additions and 57 deletions

View file

@ -6,6 +6,7 @@
#include <LibWeb/Layout/ImageBox.h>
#include <LibWeb/Painting/SVGSVGPaintable.h>
#include <LibWeb/Painting/StackingContext.h>
namespace Web::Painting {
@ -55,9 +56,21 @@ void SVGSVGPaintable::paint_svg_box(PaintContext& context, PaintableBox const& s
{
auto const& computed_values = svg_box.computed_values();
auto const& filter = svg_box.computed_values().filter();
auto const& filter = computed_values.filter();
auto masking_area = svg_box.get_masking_area();
auto needs_to_save_state = svg_box.has_css_transform() || svg_box.get_masking_area().has_value();
Gfx::CompositingAndBlendingOperator compositing_and_blending_operator;
switch (computed_values.mix_blend_mode()) {
#undef __ENUMERATE
#define __ENUMERATE(mix_blend_mode) \
case CSS::MixBlendMode::mix_blend_mode: \
compositing_and_blending_operator = Gfx::CompositingAndBlendingOperator::mix_blend_mode; \
break;
ENUMERATE_MIX_BLEND_MODES(__ENUMERATE)
#undef __ENUMERATE
}
auto needs_to_save_state = computed_values.isolation() == CSS::Isolation::Isolate || compositing_and_blending_operator != Gfx::CompositingAndBlendingOperator::Normal || svg_box.has_css_transform() || svg_box.get_masking_area().has_value();
if (needs_to_save_state) {
context.display_list_recorder().save();
@ -71,6 +84,10 @@ void SVGSVGPaintable::paint_svg_box(PaintContext& context, PaintableBox const& s
context.display_list_recorder().apply_filters(filter);
}
if (compositing_and_blending_operator != Gfx::CompositingAndBlendingOperator::Normal) {
context.display_list_recorder().apply_compositing_and_blending_operator(compositing_and_blending_operator);
}
if (svg_box.has_css_transform()) {
auto transform_matrix = svg_box.transform();
Gfx::FloatPoint transform_origin = svg_box.transform_origin().template to_type<float>();
@ -95,6 +112,10 @@ void SVGSVGPaintable::paint_svg_box(PaintContext& context, PaintableBox const& s
paint_descendants(context, svg_box, phase);
if (compositing_and_blending_operator != Gfx::CompositingAndBlendingOperator::Normal) {
context.display_list_recorder().restore();
}
if (!filter.is_empty()) {
context.display_list_recorder().restore();
}