mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 17:40:27 +00:00
LibWeb: Support using border-radius with a background-image
This commit is contained in:
parent
830632407f
commit
4e8e1492f9
Notes:
sideshowbarker
2024-07-17 10:09:19 +09:00
Author: https://github.com/MacDue Commit: https://github.com/SerenityOS/serenity/commit/4e8e1492f9 Pull-request: https://github.com/SerenityOS/serenity/pull/14289 Reviewed-by: https://github.com/linusg
1 changed files with 39 additions and 8 deletions
|
@ -10,6 +10,7 @@
|
||||||
#include <LibWeb/Layout/InitialContainingBlock.h>
|
#include <LibWeb/Layout/InitialContainingBlock.h>
|
||||||
#include <LibWeb/Layout/Node.h>
|
#include <LibWeb/Layout/Node.h>
|
||||||
#include <LibWeb/Painting/BackgroundPainting.h>
|
#include <LibWeb/Painting/BackgroundPainting.h>
|
||||||
|
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
|
||||||
#include <LibWeb/Painting/PaintContext.h>
|
#include <LibWeb/Painting/PaintContext.h>
|
||||||
|
|
||||||
namespace Web::Painting {
|
namespace Web::Painting {
|
||||||
|
@ -42,18 +43,46 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
||||||
if (background_layers && !background_layers->is_empty())
|
if (background_layers && !background_layers->is_empty())
|
||||||
color_rect = get_box(background_layers->last().clip);
|
color_rect = get_box(background_layers->last().clip);
|
||||||
|
|
||||||
Gfx::AntiAliasingPainter aa_painter { painter };
|
auto layer_is_paintable = [&](auto& layer) {
|
||||||
aa_painter.fill_rect_with_rounded_corners(color_rect.to_rounded<int>(),
|
return layer.image && layer.image->bitmap();
|
||||||
background_color, border_radii.top_left.as_corner(), border_radii.top_right.as_corner(), border_radii.bottom_right.as_corner(), border_radii.bottom_left.as_corner());
|
};
|
||||||
|
|
||||||
if (!background_layers)
|
bool has_paintable_layers = false;
|
||||||
|
if (background_layers) {
|
||||||
|
for (auto& layer : *background_layers) {
|
||||||
|
if (layer_is_paintable(layer)) {
|
||||||
|
has_paintable_layers = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<BorderRadiusCornerClipper> corner_radius_clipper {};
|
||||||
|
|
||||||
|
if (border_radii.has_any_radius()) {
|
||||||
|
if (!has_paintable_layers) {
|
||||||
|
Gfx::AntiAliasingPainter aa_painter { painter };
|
||||||
|
aa_painter.fill_rect_with_rounded_corners(color_rect.to_rounded<int>(),
|
||||||
|
background_color, border_radii.top_left.as_corner(), border_radii.top_right.as_corner(), border_radii.bottom_right.as_corner(), border_radii.bottom_left.as_corner());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto clipper = BorderRadiusCornerClipper::create(border_rect.to_rounded<int>(), border_radii);
|
||||||
|
if (!clipper.is_error())
|
||||||
|
corner_radius_clipper = clipper.release_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (corner_radius_clipper.has_value())
|
||||||
|
corner_radius_clipper->sample_under_corners(painter);
|
||||||
|
|
||||||
|
painter.fill_rect(color_rect.to_rounded<int>(), background_color);
|
||||||
|
|
||||||
|
if (!has_paintable_layers)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Note: Background layers are ordered front-to-back, so we paint them in reverse
|
// Note: Background layers are ordered front-to-back, so we paint them in reverse
|
||||||
for (int layer_index = background_layers->size() - 1; layer_index >= 0; layer_index--) {
|
for (auto& layer : background_layers->in_reverse()) {
|
||||||
auto& layer = background_layers->at(layer_index);
|
|
||||||
// TODO: Gradients!
|
// TODO: Gradients!
|
||||||
if (!layer.image || !layer.image->bitmap())
|
if (!layer_is_paintable(layer))
|
||||||
continue;
|
continue;
|
||||||
auto& image = *layer.image->bitmap();
|
auto& image = *layer.image->bitmap();
|
||||||
|
|
||||||
|
@ -230,7 +259,6 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
||||||
image_rect.set_y(image_rect.y() - y_delta);
|
image_rect.set_y(image_rect.y() - y_delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Handle rounded corners
|
|
||||||
float initial_image_x = image_rect.x();
|
float initial_image_x = image_rect.x();
|
||||||
float image_y = image_rect.y();
|
float image_y = image_rect.y();
|
||||||
while (image_y < clip_rect.bottom()) {
|
while (image_y < clip_rect.bottom()) {
|
||||||
|
@ -252,6 +280,9 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
||||||
|
|
||||||
painter.restore();
|
painter.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (corner_radius_clipper.has_value())
|
||||||
|
corner_radius_clipper->blit_corner_clipping(painter);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue