mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 07:47:37 +00:00
LibWeb: Convert border painting to new pixel units
This commit is contained in:
parent
0233627545
commit
0bf4089af9
12 changed files with 135 additions and 140 deletions
|
@ -77,7 +77,7 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
|||
|
||||
Gfx::AntiAliasingPainter aa_painter { painter };
|
||||
aa_painter.fill_rect_with_rounded_corners(context.rounded_device_rect(color_box.rect).to_type<int>(),
|
||||
background_color, color_box.radii.top_left.as_corner(), color_box.radii.top_right.as_corner(), color_box.radii.bottom_right.as_corner(), color_box.radii.bottom_left.as_corner());
|
||||
background_color, color_box.radii.top_left.as_corner(context), color_box.radii.top_right.as_corner(context), color_box.radii.bottom_right.as_corner(context), color_box.radii.bottom_left.as_corner(context));
|
||||
|
||||
if (!has_paintable_layers)
|
||||
return;
|
||||
|
@ -114,7 +114,7 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
|||
CSSPixelRect const& css_clip_rect = clip_box.rect;
|
||||
auto clip_rect = context.rounded_device_rect(css_clip_rect);
|
||||
painter.add_clip_rect(clip_rect.to_type<int>());
|
||||
ScopedCornerRadiusClip corner_clip { painter, clip_rect.to_type<int>(), clip_box.radii };
|
||||
ScopedCornerRadiusClip corner_clip { context, painter, clip_rect, clip_box.radii };
|
||||
|
||||
if (layer.clip == CSS::BackgroundBox::BorderBox) {
|
||||
// Shrink the effective clip rect if to account for the bits the borders will definitely paint over
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2022, MacDue <macdue@dueutil.tech>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
namespace Web::Painting {
|
||||
|
||||
BorderRadiiData normalized_border_radii_data(Layout::Node const& node, Gfx::FloatRect const& rect, CSS::BorderRadiusData top_left_radius, CSS::BorderRadiusData top_right_radius, CSS::BorderRadiusData bottom_right_radius, CSS::BorderRadiusData bottom_left_radius)
|
||||
BorderRadiiData normalized_border_radii_data(Layout::Node const& node, CSSPixelRect const& rect, CSS::BorderRadiusData top_left_radius, CSS::BorderRadiusData top_right_radius, CSS::BorderRadiusData bottom_right_radius, CSS::BorderRadiusData bottom_left_radius)
|
||||
{
|
||||
BorderRadiusData bottom_left_radius_px {};
|
||||
BorderRadiusData bottom_right_radius_px {};
|
||||
|
@ -34,15 +34,15 @@ BorderRadiiData normalized_border_radii_data(Layout::Node const& node, Gfx::Floa
|
|||
top_right_radius_px.vertical_radius = top_right_radius.vertical_radius.resolved(node, height_length).to_px(node);
|
||||
|
||||
// Scale overlapping curves according to https://www.w3.org/TR/css-backgrounds-3/#corner-overlap
|
||||
auto f = 1.0f;
|
||||
auto width_reciprocal = 1.0f / rect.width();
|
||||
auto height_reciprocal = 1.0f / rect.height();
|
||||
CSSPixels f = 1.0f;
|
||||
auto width_reciprocal = 1.0f / rect.width().value();
|
||||
auto height_reciprocal = 1.0f / rect.height().value();
|
||||
f = max(f, width_reciprocal * (top_left_radius_px.horizontal_radius + top_right_radius_px.horizontal_radius));
|
||||
f = max(f, height_reciprocal * (top_right_radius_px.vertical_radius + bottom_right_radius_px.vertical_radius));
|
||||
f = max(f, width_reciprocal * (bottom_left_radius_px.horizontal_radius + bottom_right_radius_px.horizontal_radius));
|
||||
f = max(f, height_reciprocal * (top_left_radius_px.vertical_radius + bottom_left_radius_px.vertical_radius));
|
||||
|
||||
f = 1.0f / f;
|
||||
f = 1.0f / f.value();
|
||||
|
||||
top_left_radius_px.horizontal_radius *= f;
|
||||
top_left_radius_px.vertical_radius *= f;
|
||||
|
@ -56,7 +56,7 @@ BorderRadiiData normalized_border_radii_data(Layout::Node const& node, Gfx::Floa
|
|||
return BorderRadiiData { top_left_radius_px, top_right_radius_px, bottom_right_radius_px, bottom_left_radius_px };
|
||||
}
|
||||
|
||||
void paint_border(PaintContext& context, BorderEdge edge, Gfx::IntRect const& rect, BorderRadiiData const& border_radii_data, BordersData const& borders_data)
|
||||
void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& rect, BorderRadiiData const& border_radii_data, BordersData const& borders_data)
|
||||
{
|
||||
auto const& border_data = [&] {
|
||||
switch (edge) {
|
||||
|
@ -71,20 +71,20 @@ void paint_border(PaintContext& context, BorderEdge edge, Gfx::IntRect const& re
|
|||
}
|
||||
}();
|
||||
|
||||
float width = border_data.width;
|
||||
CSSPixels width = border_data.width;
|
||||
if (width <= 0)
|
||||
return;
|
||||
|
||||
auto color = border_data.color;
|
||||
auto border_style = border_data.line_style;
|
||||
int int_width = ceilf(width);
|
||||
auto device_pixel_width = context.enclosing_device_pixels(width);
|
||||
|
||||
struct Points {
|
||||
Gfx::IntPoint p1;
|
||||
Gfx::IntPoint p2;
|
||||
DevicePixelPoint p1;
|
||||
DevicePixelPoint p2;
|
||||
};
|
||||
|
||||
auto points_for_edge = [](BorderEdge edge, Gfx::IntRect const& rect) -> Points {
|
||||
auto points_for_edge = [](BorderEdge edge, DevicePixelRect const& rect) -> Points {
|
||||
switch (edge) {
|
||||
case BorderEdge::Top:
|
||||
return { rect.top_left(), rect.top_right() };
|
||||
|
@ -117,28 +117,28 @@ void paint_border(PaintContext& context, BorderEdge edge, Gfx::IntRect const& re
|
|||
auto [p1, p2] = points_for_edge(edge, rect);
|
||||
switch (edge) {
|
||||
case BorderEdge::Top:
|
||||
p1.translate_by(int_width / 2, int_width / 2);
|
||||
p2.translate_by(-int_width / 2, int_width / 2);
|
||||
p1.translate_by(device_pixel_width / 2, device_pixel_width / 2);
|
||||
p2.translate_by(-device_pixel_width / 2, device_pixel_width / 2);
|
||||
break;
|
||||
case BorderEdge::Right:
|
||||
p1.translate_by(-int_width / 2, int_width / 2);
|
||||
p2.translate_by(-int_width / 2, -int_width / 2);
|
||||
p1.translate_by(-device_pixel_width / 2, device_pixel_width / 2);
|
||||
p2.translate_by(-device_pixel_width / 2, -device_pixel_width / 2);
|
||||
break;
|
||||
case BorderEdge::Bottom:
|
||||
p1.translate_by(int_width / 2, -int_width / 2);
|
||||
p2.translate_by(-int_width / 2, -int_width / 2);
|
||||
p1.translate_by(device_pixel_width / 2, -device_pixel_width / 2);
|
||||
p2.translate_by(-device_pixel_width / 2, -device_pixel_width / 2);
|
||||
break;
|
||||
case BorderEdge::Left:
|
||||
p1.translate_by(int_width / 2, int_width / 2);
|
||||
p2.translate_by(int_width / 2, -int_width / 2);
|
||||
p1.translate_by(device_pixel_width / 2, device_pixel_width / 2);
|
||||
p2.translate_by(device_pixel_width / 2, -device_pixel_width / 2);
|
||||
break;
|
||||
}
|
||||
if (border_style == CSS::LineStyle::Dotted) {
|
||||
Gfx::AntiAliasingPainter aa_painter { context.painter() };
|
||||
aa_painter.draw_line(p1.to_type<float>(), p2.to_type<float>(), color, int_width, gfx_line_style);
|
||||
aa_painter.draw_line(p1.to_type<int>(), p2.to_type<int>(), color, device_pixel_width.value(), gfx_line_style);
|
||||
return;
|
||||
}
|
||||
context.painter().draw_line(p1, p2, color, int_width, gfx_line_style);
|
||||
context.painter().draw_line(p1.to_type<int>(), p2.to_type<int>(), color, device_pixel_width.value(), gfx_line_style);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -146,19 +146,17 @@ void paint_border(PaintContext& context, BorderEdge edge, Gfx::IntRect const& re
|
|||
// Note: Using fill_rect() here since draw_line() produces some overlapping pixels
|
||||
// at the end of a line, which cause issues on borders with transparency.
|
||||
p2.translate_by(1, 1);
|
||||
context.painter().fill_rect(Gfx::IntRect::from_two_points(p1, p2), color);
|
||||
context.painter().fill_rect(Gfx::IntRect::from_two_points(p1.template to_type<int>(), p2.template to_type<int>()), color);
|
||||
};
|
||||
|
||||
auto draw_border = [&](auto const& border, auto const& radius, auto const& opposite_border, auto const& opposite_radius, auto p1_step_translate, auto p2_step_translate) {
|
||||
auto [p1, p2] = points_for_edge(edge, rect);
|
||||
auto current_p1 = p1.to_type<float>();
|
||||
auto current_p2 = p2.to_type<float>();
|
||||
auto p1_step = radius ? 0 : border.width / static_cast<float>(int_width);
|
||||
auto p2_step = opposite_radius ? 0 : opposite_border.width / static_cast<float>(int_width);
|
||||
for (int i = 0; i < int_width; ++i) {
|
||||
draw_horizontal_or_vertical_line(current_p1.to_type<int>(), current_p2.to_type<int>());
|
||||
p1_step_translate(current_p1, p1_step);
|
||||
p2_step_translate(current_p2, p2_step);
|
||||
auto p1_step = radius ? 0 : border.width / static_cast<float>(device_pixel_width.value());
|
||||
auto p2_step = opposite_radius ? 0 : opposite_border.width / static_cast<float>(device_pixel_width.value());
|
||||
for (DevicePixels i = 0; i < device_pixel_width; ++i) {
|
||||
draw_horizontal_or_vertical_line(p1, p2);
|
||||
p1_step_translate(p1, p1_step);
|
||||
p2_step_translate(p2, p2_step);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -209,10 +207,10 @@ void paint_border(PaintContext& context, BorderEdge edge, Gfx::IntRect const& re
|
|||
}
|
||||
}
|
||||
|
||||
RefPtr<Gfx::Bitmap> get_cached_corner_bitmap(Gfx::IntSize corners_size)
|
||||
RefPtr<Gfx::Bitmap> get_cached_corner_bitmap(DevicePixelSize corners_size)
|
||||
{
|
||||
auto allocate_mask_bitmap = [&]() -> RefPtr<Gfx::Bitmap> {
|
||||
auto bitmap = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, corners_size);
|
||||
auto bitmap = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, corners_size.to_type<int>());
|
||||
if (!bitmap.is_error())
|
||||
return bitmap.release_value();
|
||||
return nullptr;
|
||||
|
@ -221,7 +219,7 @@ RefPtr<Gfx::Bitmap> get_cached_corner_bitmap(Gfx::IntSize corners_size)
|
|||
static thread_local auto corner_bitmap = allocate_mask_bitmap();
|
||||
// Only reallocate the corner bitmap is the existing one is too small.
|
||||
// (should mean no more allocations after the first paint -- amortised zero allocations :^))
|
||||
if (corner_bitmap && corner_bitmap->rect().size().contains(corners_size)) {
|
||||
if (corner_bitmap && corner_bitmap->rect().size().contains(corners_size.to_type<int>())) {
|
||||
Gfx::Painter painter { *corner_bitmap };
|
||||
painter.clear_rect({ { 0, 0 }, corners_size }, Gfx::Color());
|
||||
} else {
|
||||
|
@ -234,17 +232,17 @@ RefPtr<Gfx::Bitmap> get_cached_corner_bitmap(Gfx::IntSize corners_size)
|
|||
return corner_bitmap;
|
||||
}
|
||||
|
||||
void paint_all_borders(PaintContext& context, Gfx::FloatRect const& bordered_rect, BorderRadiiData const& border_radii_data, BordersData const& borders_data)
|
||||
void paint_all_borders(PaintContext& context, CSSPixelRect const& bordered_rect, BorderRadiiData const& border_radii_data, BordersData const& borders_data)
|
||||
{
|
||||
if (borders_data.top.width <= 0 && borders_data.right.width <= 0 && borders_data.left.width <= 0 && borders_data.bottom.width <= 0)
|
||||
return;
|
||||
|
||||
Gfx::IntRect border_rect = bordered_rect.to_rounded<int>();
|
||||
auto border_rect = context.rounded_device_rect(bordered_rect);
|
||||
|
||||
auto top_left = border_radii_data.top_left.as_corner();
|
||||
auto top_right = border_radii_data.top_right.as_corner();
|
||||
auto bottom_right = border_radii_data.bottom_right.as_corner();
|
||||
auto bottom_left = border_radii_data.bottom_left.as_corner();
|
||||
auto top_left = border_radii_data.top_left.as_corner(context);
|
||||
auto top_right = border_radii_data.top_right.as_corner(context);
|
||||
auto bottom_right = border_radii_data.bottom_right.as_corner(context);
|
||||
auto bottom_left = border_radii_data.bottom_left.as_corner(context);
|
||||
|
||||
// Disable border radii if the corresponding borders don't exist:
|
||||
if (borders_data.bottom.width <= 0 && borders_data.left.width <= 0)
|
||||
|
@ -256,32 +254,28 @@ void paint_all_borders(PaintContext& context, Gfx::FloatRect const& bordered_rec
|
|||
if (borders_data.top.width <= 0 && borders_data.right.width <= 0)
|
||||
top_right = { 0, 0 };
|
||||
|
||||
auto int_width = [&](auto value) -> int {
|
||||
return ceilf(value);
|
||||
};
|
||||
|
||||
Gfx::IntRect top_border_rect = {
|
||||
DevicePixelRect top_border_rect = {
|
||||
border_rect.x() + top_left.horizontal_radius,
|
||||
border_rect.y(),
|
||||
border_rect.width() - top_left.horizontal_radius - top_right.horizontal_radius,
|
||||
int_width(borders_data.top.width)
|
||||
context.enclosing_device_pixels(borders_data.top.width)
|
||||
};
|
||||
Gfx::IntRect right_border_rect = {
|
||||
border_rect.x() + (border_rect.width() - int_width(borders_data.right.width)),
|
||||
DevicePixelRect right_border_rect = {
|
||||
border_rect.x() + (border_rect.width() - context.enclosing_device_pixels(borders_data.right.width)),
|
||||
border_rect.y() + top_right.vertical_radius,
|
||||
int_width(borders_data.right.width),
|
||||
context.enclosing_device_pixels(borders_data.right.width),
|
||||
border_rect.height() - top_right.vertical_radius - bottom_right.vertical_radius
|
||||
};
|
||||
Gfx::IntRect bottom_border_rect = {
|
||||
DevicePixelRect bottom_border_rect = {
|
||||
border_rect.x() + bottom_left.horizontal_radius,
|
||||
border_rect.y() + (border_rect.height() - int_width(borders_data.bottom.width)),
|
||||
border_rect.y() + (border_rect.height() - context.enclosing_device_pixels(borders_data.bottom.width)),
|
||||
border_rect.width() - bottom_left.horizontal_radius - bottom_right.horizontal_radius,
|
||||
int_width(borders_data.bottom.width)
|
||||
context.enclosing_device_pixels(borders_data.bottom.width)
|
||||
};
|
||||
Gfx::IntRect left_border_rect = {
|
||||
DevicePixelRect left_border_rect = {
|
||||
border_rect.x(),
|
||||
border_rect.y() + top_left.vertical_radius,
|
||||
int_width(borders_data.left.width),
|
||||
context.enclosing_device_pixels(borders_data.left.width),
|
||||
border_rect.height() - top_left.vertical_radius - bottom_left.vertical_radius
|
||||
};
|
||||
|
||||
|
@ -308,16 +302,16 @@ void paint_all_borders(PaintContext& context, Gfx::FloatRect const& bordered_rec
|
|||
return;
|
||||
|
||||
// Cache the smallest possible bitmap to render just the corners for the border.
|
||||
auto expand_width = abs(int_width(borders_data.left.width) - int_width(borders_data.right.width));
|
||||
auto expand_height = abs(int_width(borders_data.top.width) - int_width(borders_data.bottom.width));
|
||||
Gfx::IntRect corner_mask_rect {
|
||||
auto expand_width = abs(context.enclosing_device_pixels(borders_data.left.width) - context.enclosing_device_pixels(borders_data.right.width));
|
||||
auto expand_height = abs(context.enclosing_device_pixels(borders_data.top.width) - context.enclosing_device_pixels(borders_data.bottom.width));
|
||||
DevicePixelRect corner_mask_rect {
|
||||
0, 0,
|
||||
max(
|
||||
top_left.horizontal_radius + top_right.horizontal_radius + expand_width,
|
||||
bottom_left.horizontal_radius + bottom_right.horizontal_radius + expand_height),
|
||||
top_left.horizontal_radius + top_right.horizontal_radius + expand_width.value(),
|
||||
bottom_left.horizontal_radius + bottom_right.horizontal_radius + expand_height.value()),
|
||||
max(
|
||||
top_left.vertical_radius + bottom_left.vertical_radius + expand_width,
|
||||
top_right.vertical_radius + bottom_right.vertical_radius + expand_height)
|
||||
top_left.vertical_radius + bottom_left.vertical_radius + expand_width.value(),
|
||||
top_right.vertical_radius + bottom_right.vertical_radius + expand_height.value())
|
||||
};
|
||||
|
||||
auto corner_bitmap = get_cached_corner_bitmap(corner_mask_rect.size());
|
||||
|
@ -331,27 +325,27 @@ void paint_all_borders(PaintContext& context, Gfx::FloatRect const& bordered_rec
|
|||
// TODO: Support various line styles on the corners (dotted, dashes, etc)
|
||||
|
||||
// Paint the outer (minimal) corner rounded rectangle:
|
||||
aa_painter.fill_rect_with_rounded_corners(corner_mask_rect, border_color_no_alpha, top_left, top_right, bottom_right, bottom_left);
|
||||
aa_painter.fill_rect_with_rounded_corners(corner_mask_rect.to_type<int>(), border_color_no_alpha, top_left, top_right, bottom_right, bottom_left);
|
||||
|
||||
// Subtract the inner corner rectangle:
|
||||
auto inner_corner_mask_rect = corner_mask_rect.shrunken(
|
||||
int_width(borders_data.top.width),
|
||||
int_width(borders_data.right.width),
|
||||
int_width(borders_data.bottom.width),
|
||||
int_width(borders_data.left.width));
|
||||
context.enclosing_device_pixels(borders_data.top.width),
|
||||
context.enclosing_device_pixels(borders_data.right.width),
|
||||
context.enclosing_device_pixels(borders_data.bottom.width),
|
||||
context.enclosing_device_pixels(borders_data.left.width));
|
||||
auto inner_top_left = top_left;
|
||||
auto inner_top_right = top_right;
|
||||
auto inner_bottom_right = bottom_right;
|
||||
auto inner_bottom_left = bottom_left;
|
||||
inner_top_left.horizontal_radius = max(0, inner_top_left.horizontal_radius - int_width(borders_data.left.width));
|
||||
inner_top_left.vertical_radius = max(0, inner_top_left.vertical_radius - int_width(borders_data.top.width));
|
||||
inner_top_right.horizontal_radius = max(0, inner_top_right.horizontal_radius - int_width(borders_data.right.width));
|
||||
inner_top_right.vertical_radius = max(0, inner_top_right.vertical_radius - int_width(borders_data.top.width));
|
||||
inner_bottom_right.horizontal_radius = max(0, inner_bottom_right.horizontal_radius - int_width(borders_data.right.width));
|
||||
inner_bottom_right.vertical_radius = max(0, inner_bottom_right.vertical_radius - int_width(borders_data.bottom.width));
|
||||
inner_bottom_left.horizontal_radius = max(0, inner_bottom_left.horizontal_radius - int_width(borders_data.left.width));
|
||||
inner_bottom_left.vertical_radius = max(0, inner_bottom_left.vertical_radius - int_width(borders_data.bottom.width));
|
||||
aa_painter.fill_rect_with_rounded_corners(inner_corner_mask_rect, border_color_no_alpha, inner_top_left, inner_top_right, inner_bottom_right, inner_bottom_left, Gfx::AntiAliasingPainter::BlendMode::AlphaSubtract);
|
||||
inner_top_left.horizontal_radius = max(0, inner_top_left.horizontal_radius - context.enclosing_device_pixels(borders_data.left.width).value());
|
||||
inner_top_left.vertical_radius = max(0, inner_top_left.vertical_radius - context.enclosing_device_pixels(borders_data.top.width).value());
|
||||
inner_top_right.horizontal_radius = max(0, inner_top_right.horizontal_radius - context.enclosing_device_pixels(borders_data.right.width).value());
|
||||
inner_top_right.vertical_radius = max(0, inner_top_right.vertical_radius - context.enclosing_device_pixels(borders_data.top.width).value());
|
||||
inner_bottom_right.horizontal_radius = max(0, inner_bottom_right.horizontal_radius - context.enclosing_device_pixels(borders_data.right.width).value());
|
||||
inner_bottom_right.vertical_radius = max(0, inner_bottom_right.vertical_radius - context.enclosing_device_pixels(borders_data.bottom.width).value());
|
||||
inner_bottom_left.horizontal_radius = max(0, inner_bottom_left.horizontal_radius - context.enclosing_device_pixels(borders_data.left.width).value());
|
||||
inner_bottom_left.vertical_radius = max(0, inner_bottom_left.vertical_radius - context.enclosing_device_pixels(borders_data.bottom.width).value());
|
||||
aa_painter.fill_rect_with_rounded_corners(inner_corner_mask_rect.to_type<int>(), border_color_no_alpha, inner_top_left, inner_top_right, inner_bottom_right, inner_bottom_left, Gfx::AntiAliasingPainter::BlendMode::AlphaSubtract);
|
||||
|
||||
// TODO: Support dual color corners. Other browsers will render a rounded corner between two borders of
|
||||
// different colors using both colours, normally split at a 45 degree angle (though the exact angle is interpolated).
|
||||
|
@ -370,16 +364,16 @@ void paint_all_borders(PaintContext& context, Gfx::FloatRect const& bordered_rec
|
|||
|
||||
// Blit the corners into to their corresponding locations:
|
||||
if (top_left)
|
||||
blit_corner(border_rect.top_left(), top_left.as_rect(), pick_corner_color(borders_data.top, borders_data.left));
|
||||
blit_corner(border_rect.top_left().to_type<int>(), top_left.as_rect(), pick_corner_color(borders_data.top, borders_data.left));
|
||||
|
||||
if (top_right)
|
||||
blit_corner(border_rect.top_right().translated(-top_right.horizontal_radius + 1, 0), top_right.as_rect().translated(corner_mask_rect.width() - top_right.horizontal_radius, 0), pick_corner_color(borders_data.top, borders_data.right));
|
||||
blit_corner(border_rect.top_right().to_type<int>().translated(-top_right.horizontal_radius + 1, 0), top_right.as_rect().translated(corner_mask_rect.width().value() - top_right.horizontal_radius, 0), pick_corner_color(borders_data.top, borders_data.right));
|
||||
|
||||
if (bottom_right)
|
||||
blit_corner(border_rect.bottom_right().translated(-bottom_right.horizontal_radius + 1, -bottom_right.vertical_radius + 1), bottom_right.as_rect().translated(corner_mask_rect.width() - bottom_right.horizontal_radius, corner_mask_rect.height() - bottom_right.vertical_radius), pick_corner_color(borders_data.bottom, borders_data.right));
|
||||
blit_corner(border_rect.bottom_right().to_type<int>().translated(-bottom_right.horizontal_radius + 1, -bottom_right.vertical_radius + 1), bottom_right.as_rect().translated(corner_mask_rect.width().value() - bottom_right.horizontal_radius, corner_mask_rect.height().value() - bottom_right.vertical_radius), pick_corner_color(borders_data.bottom, borders_data.right));
|
||||
|
||||
if (bottom_left)
|
||||
blit_corner(border_rect.bottom_left().translated(0, -bottom_left.vertical_radius + 1), bottom_left.as_rect().translated(0, corner_mask_rect.height() - bottom_left.vertical_radius), pick_corner_color(borders_data.bottom, borders_data.left));
|
||||
blit_corner(border_rect.bottom_left().to_type<int>().translated(0, -bottom_left.vertical_radius + 1), bottom_left.as_rect().translated(0, corner_mask_rect.height().value() - bottom_left.vertical_radius), pick_corner_color(borders_data.bottom, borders_data.left));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,26 +13,26 @@
|
|||
namespace Web::Painting {
|
||||
|
||||
struct BorderRadiusData {
|
||||
float horizontal_radius { 0 };
|
||||
float vertical_radius { 0 };
|
||||
CSSPixels horizontal_radius { 0 };
|
||||
CSSPixels vertical_radius { 0 };
|
||||
|
||||
Gfx::AntiAliasingPainter::CornerRadius as_corner() const
|
||||
Gfx::AntiAliasingPainter::CornerRadius as_corner(PaintContext& context) const
|
||||
{
|
||||
return Gfx::AntiAliasingPainter::CornerRadius {
|
||||
static_cast<int>(horizontal_radius),
|
||||
static_cast<int>(vertical_radius)
|
||||
context.floored_device_pixels(horizontal_radius).value(),
|
||||
context.floored_device_pixels(vertical_radius).value()
|
||||
};
|
||||
};
|
||||
|
||||
inline operator bool() const
|
||||
{
|
||||
return static_cast<int>(horizontal_radius) > 0 && static_cast<int>(vertical_radius) > 0;
|
||||
return horizontal_radius > 0 && vertical_radius > 0;
|
||||
}
|
||||
|
||||
inline void shrink(float horizontal, float vertical)
|
||||
inline void shrink(CSSPixels horizontal, CSSPixels vertical)
|
||||
{
|
||||
horizontal_radius = max(0, horizontal_radius - horizontal);
|
||||
vertical_radius = max(0, vertical_radius - vertical);
|
||||
horizontal_radius = max(CSSPixels(0), horizontal_radius - horizontal);
|
||||
vertical_radius = max(CSSPixels(0), vertical_radius - vertical);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,7 @@ struct BorderRadiiData {
|
|||
return top_left || top_right || bottom_right || bottom_left;
|
||||
}
|
||||
|
||||
inline void shrink(float top, float right, float bottom, float left)
|
||||
inline void shrink(CSSPixels top, CSSPixels right, CSSPixels bottom, CSSPixels left)
|
||||
{
|
||||
top_left.shrink(left, top);
|
||||
top_right.shrink(right, top);
|
||||
|
@ -56,7 +56,7 @@ struct BorderRadiiData {
|
|||
}
|
||||
};
|
||||
|
||||
BorderRadiiData normalized_border_radii_data(Layout::Node const&, Gfx::FloatRect const&, CSS::BorderRadiusData top_left_radius, CSS::BorderRadiusData top_right_radius, CSS::BorderRadiusData bottom_right_radius, CSS::BorderRadiusData bottom_left_radius);
|
||||
BorderRadiiData normalized_border_radii_data(Layout::Node const&, CSSPixelRect const&, CSS::BorderRadiusData top_left_radius, CSS::BorderRadiusData top_right_radius, CSS::BorderRadiusData bottom_right_radius, CSS::BorderRadiusData bottom_left_radius);
|
||||
|
||||
enum class BorderEdge {
|
||||
Top,
|
||||
|
@ -71,9 +71,9 @@ struct BordersData {
|
|||
CSS::BorderData left;
|
||||
};
|
||||
|
||||
RefPtr<Gfx::Bitmap> get_cached_corner_bitmap(Gfx::IntSize corners_size);
|
||||
RefPtr<Gfx::Bitmap> get_cached_corner_bitmap(DevicePixelSize corners_size);
|
||||
|
||||
void paint_border(PaintContext& context, BorderEdge edge, Gfx::IntRect const& rect, BorderRadiiData const& border_radii_data, BordersData const& borders_data);
|
||||
void paint_all_borders(PaintContext& context, Gfx::FloatRect const& bordered_rect, BorderRadiiData const& border_radii_data, BordersData const&);
|
||||
void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& rect, BorderRadiiData const& border_radii_data, BordersData const& borders_data);
|
||||
void paint_all_borders(PaintContext& context, CSSPixelRect const& bordered_rect, BorderRadiiData const& border_radii_data, BordersData const&);
|
||||
|
||||
}
|
||||
|
|
|
@ -10,16 +10,16 @@
|
|||
|
||||
namespace Web::Painting {
|
||||
|
||||
ErrorOr<BorderRadiusCornerClipper> BorderRadiusCornerClipper::create(Gfx::IntRect const& border_rect, BorderRadiiData const& border_radii, CornerClip corner_clip, UseCachedBitmap use_cached_bitmap)
|
||||
ErrorOr<BorderRadiusCornerClipper> BorderRadiusCornerClipper::create(PaintContext& context, DevicePixelRect const& border_rect, BorderRadiiData const& border_radii, CornerClip corner_clip, UseCachedBitmap use_cached_bitmap)
|
||||
{
|
||||
VERIFY(border_radii.has_any_radius());
|
||||
|
||||
auto top_left = border_radii.top_left.as_corner();
|
||||
auto top_right = border_radii.top_right.as_corner();
|
||||
auto bottom_right = border_radii.bottom_right.as_corner();
|
||||
auto bottom_left = border_radii.bottom_left.as_corner();
|
||||
auto top_left = border_radii.top_left.as_corner(context);
|
||||
auto top_right = border_radii.top_right.as_corner(context);
|
||||
auto bottom_right = border_radii.bottom_right.as_corner(context);
|
||||
auto bottom_left = border_radii.bottom_left.as_corner(context);
|
||||
|
||||
Gfx::IntSize corners_bitmap_size {
|
||||
DevicePixelSize corners_bitmap_size {
|
||||
max(
|
||||
top_left.horizontal_radius + top_right.horizontal_radius,
|
||||
bottom_left.horizontal_radius + bottom_right.horizontal_radius),
|
||||
|
@ -34,7 +34,7 @@ ErrorOr<BorderRadiusCornerClipper> BorderRadiusCornerClipper::create(Gfx::IntRec
|
|||
if (!corner_bitmap)
|
||||
return Error::from_errno(ENOMEM);
|
||||
} else {
|
||||
corner_bitmap = TRY(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, corners_bitmap_size));
|
||||
corner_bitmap = TRY(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, corners_bitmap_size.to_type<int>()));
|
||||
}
|
||||
|
||||
CornerData corner_data {
|
||||
|
@ -60,7 +60,7 @@ void BorderRadiusCornerClipper::sample_under_corners(Gfx::Painter& page_painter)
|
|||
corner_aa_painter.fill_rect_with_rounded_corners(corner_rect, Color::NamedColor::Black,
|
||||
m_data.corner_radii.top_left, m_data.corner_radii.top_right, m_data.corner_radii.bottom_right, m_data.corner_radii.bottom_left);
|
||||
|
||||
auto copy_page_masked = [&](auto const& mask_src, auto const& page_location) {
|
||||
auto copy_page_masked = [&](Gfx::IntRect const& mask_src, Gfx::IntPoint const& page_location) {
|
||||
for (int row = 0; row < mask_src.height(); ++row) {
|
||||
for (int col = 0; col < mask_src.width(); ++col) {
|
||||
auto corner_location = mask_src.location().translated(col, row);
|
||||
|
@ -81,13 +81,13 @@ void BorderRadiusCornerClipper::sample_under_corners(Gfx::Painter& page_painter)
|
|||
|
||||
// Copy the pixels under the corner mask (using the alpha of the mask):
|
||||
if (m_data.corner_radii.top_left)
|
||||
copy_page_masked(m_data.corner_radii.top_left.as_rect().translated(m_data.bitmap_locations.top_left), m_data.page_locations.top_left);
|
||||
copy_page_masked(m_data.corner_radii.top_left.as_rect().translated(m_data.bitmap_locations.top_left.to_type<int>()), m_data.page_locations.top_left.to_type<int>());
|
||||
if (m_data.corner_radii.top_right)
|
||||
copy_page_masked(m_data.corner_radii.top_right.as_rect().translated(m_data.bitmap_locations.top_right), m_data.page_locations.top_right);
|
||||
copy_page_masked(m_data.corner_radii.top_right.as_rect().translated(m_data.bitmap_locations.top_right.to_type<int>()), m_data.page_locations.top_right.to_type<int>());
|
||||
if (m_data.corner_radii.bottom_right)
|
||||
copy_page_masked(m_data.corner_radii.bottom_right.as_rect().translated(m_data.bitmap_locations.bottom_right), m_data.page_locations.bottom_right);
|
||||
copy_page_masked(m_data.corner_radii.bottom_right.as_rect().translated(m_data.bitmap_locations.bottom_right.to_type<int>()), m_data.page_locations.bottom_right.to_type<int>());
|
||||
if (m_data.corner_radii.bottom_left)
|
||||
copy_page_masked(m_data.corner_radii.bottom_left.as_rect().translated(m_data.bitmap_locations.bottom_left), m_data.page_locations.bottom_left);
|
||||
copy_page_masked(m_data.corner_radii.bottom_left.as_rect().translated(m_data.bitmap_locations.bottom_left.to_type<int>()), m_data.page_locations.bottom_left.to_type<int>());
|
||||
|
||||
m_has_sampled = true;
|
||||
}
|
||||
|
@ -98,13 +98,13 @@ void BorderRadiusCornerClipper::blit_corner_clipping(Gfx::Painter& painter)
|
|||
|
||||
// Restore the corners:
|
||||
if (m_data.corner_radii.top_left)
|
||||
painter.blit(m_data.page_locations.top_left, *m_corner_bitmap, m_data.corner_radii.top_left.as_rect().translated(m_data.bitmap_locations.top_left));
|
||||
painter.blit(m_data.page_locations.top_left.to_type<int>(), *m_corner_bitmap, m_data.corner_radii.top_left.as_rect().translated(m_data.bitmap_locations.top_left.to_type<int>()));
|
||||
if (m_data.corner_radii.top_right)
|
||||
painter.blit(m_data.page_locations.top_right, *m_corner_bitmap, m_data.corner_radii.top_right.as_rect().translated(m_data.bitmap_locations.top_right));
|
||||
painter.blit(m_data.page_locations.top_right.to_type<int>(), *m_corner_bitmap, m_data.corner_radii.top_right.as_rect().translated(m_data.bitmap_locations.top_right.to_type<int>()));
|
||||
if (m_data.corner_radii.bottom_right)
|
||||
painter.blit(m_data.page_locations.bottom_right, *m_corner_bitmap, m_data.corner_radii.bottom_right.as_rect().translated(m_data.bitmap_locations.bottom_right));
|
||||
painter.blit(m_data.page_locations.bottom_right.to_type<int>(), *m_corner_bitmap, m_data.corner_radii.bottom_right.as_rect().translated(m_data.bitmap_locations.bottom_right.to_type<int>()));
|
||||
if (m_data.corner_radii.bottom_left)
|
||||
painter.blit(m_data.page_locations.bottom_left, *m_corner_bitmap, m_data.corner_radii.bottom_left.as_rect().translated(m_data.bitmap_locations.bottom_left));
|
||||
painter.blit(m_data.page_locations.bottom_left.to_type<int>(), *m_corner_bitmap, m_data.corner_radii.bottom_left.as_rect().translated(m_data.bitmap_locations.bottom_left.to_type<int>()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
No
|
||||
};
|
||||
|
||||
static ErrorOr<BorderRadiusCornerClipper> create(Gfx::IntRect const& border_rect, BorderRadiiData const& border_radii, CornerClip corner_clip = CornerClip::Outside, UseCachedBitmap use_cached_bitmap = UseCachedBitmap::Yes);
|
||||
static ErrorOr<BorderRadiusCornerClipper> create(PaintContext&, DevicePixelRect const& border_rect, BorderRadiiData const& border_radii, CornerClip corner_clip = CornerClip::Outside, UseCachedBitmap use_cached_bitmap = UseCachedBitmap::Yes);
|
||||
|
||||
void sample_under_corners(Gfx::Painter& page_painter);
|
||||
void blit_corner_clipping(Gfx::Painter& page_painter);
|
||||
|
@ -38,14 +38,14 @@ private:
|
|||
CornerRadius bottom_left;
|
||||
} corner_radii;
|
||||
struct CornerLocations {
|
||||
Gfx::IntPoint top_left;
|
||||
Gfx::IntPoint top_right;
|
||||
Gfx::IntPoint bottom_right;
|
||||
Gfx::IntPoint bottom_left;
|
||||
DevicePixelPoint top_left;
|
||||
DevicePixelPoint top_right;
|
||||
DevicePixelPoint bottom_right;
|
||||
DevicePixelPoint bottom_left;
|
||||
};
|
||||
CornerLocations page_locations;
|
||||
CornerLocations bitmap_locations;
|
||||
Gfx::IntSize corner_bitmap_size;
|
||||
DevicePixelSize corner_bitmap_size;
|
||||
} m_data;
|
||||
|
||||
NonnullRefPtr<Gfx::Bitmap> m_corner_bitmap;
|
||||
|
@ -61,11 +61,11 @@ private:
|
|||
};
|
||||
|
||||
struct ScopedCornerRadiusClip {
|
||||
ScopedCornerRadiusClip(Gfx::Painter& painter, Gfx::IntRect const& border_rect, BorderRadiiData const& border_radii, CornerClip corner_clip = CornerClip::Outside, BorderRadiusCornerClipper::UseCachedBitmap use_cached_bitmap = BorderRadiusCornerClipper::UseCachedBitmap::Yes)
|
||||
ScopedCornerRadiusClip(PaintContext& context, Gfx::Painter& painter, DevicePixelRect const& border_rect, BorderRadiiData const& border_radii, CornerClip corner_clip = CornerClip::Outside, BorderRadiusCornerClipper::UseCachedBitmap use_cached_bitmap = BorderRadiusCornerClipper::UseCachedBitmap::Yes)
|
||||
: m_painter(painter)
|
||||
{
|
||||
if (border_radii.has_any_radius()) {
|
||||
auto clipper = BorderRadiusCornerClipper::create(border_rect, border_radii, corner_clip, use_cached_bitmap);
|
||||
auto clipper = BorderRadiusCornerClipper::create(context, border_rect, border_radii, corner_clip, use_cached_bitmap);
|
||||
if (!clipper.is_error()) {
|
||||
m_corner_clipper = clipper.release_value();
|
||||
m_corner_clipper->sample_under_corners(m_painter);
|
||||
|
|
|
@ -31,8 +31,8 @@ void CanvasPaintable::paint(PaintContext& context, PaintPhase phase) const
|
|||
PaintableBox::paint(context, phase);
|
||||
|
||||
if (phase == PaintPhase::Foreground) {
|
||||
auto canvas_rect = absolute_rect().to_rounded<int>();
|
||||
ScopedCornerRadiusClip corner_clip { context.painter(), canvas_rect, normalized_border_radii_data(ShrinkRadiiForBorders::Yes) };
|
||||
auto canvas_rect = context.rounded_device_rect(absolute_rect().to_type<CSSPixels>());
|
||||
ScopedCornerRadiusClip corner_clip { context, context.painter(), canvas_rect, normalized_border_radii_data(ShrinkRadiiForBorders::Yes) };
|
||||
|
||||
// FIXME: This should be done at a different level.
|
||||
if (is_out_of_view(context))
|
||||
|
@ -41,7 +41,7 @@ void CanvasPaintable::paint(PaintContext& context, PaintPhase phase) const
|
|||
if (layout_box().dom_node().bitmap()) {
|
||||
// FIXME: Remove this const_cast.
|
||||
const_cast<HTML::HTMLCanvasElement&>(layout_box().dom_node()).present();
|
||||
context.painter().draw_scaled_bitmap(canvas_rect, *layout_box().dom_node().bitmap(), layout_box().dom_node().bitmap()->rect(), 1.0f, to_gfx_scaling_mode(computed_values().image_rendering()));
|
||||
context.painter().draw_scaled_bitmap(canvas_rect.to_type<int>(), *layout_box().dom_node().bitmap(), layout_box().dom_node().bitmap()->rect(), 1.0f, to_gfx_scaling_mode(computed_values().image_rendering()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ void apply_backdrop_filter(PaintContext& context, Layout::Node const& node, Gfx:
|
|||
// FIXME: 3. If element B has any transforms (between B and the Backdrop Root), apply the inverse of those transforms to the contents of T’.
|
||||
|
||||
// 4. Apply a clip to the contents of T’, using the border box of element B, including border-radius if specified. Note that the children of B are not considered for the sizing or location of this clip.
|
||||
ScopedCornerRadiusClip corner_clipper { context.painter(), backdrop_region, border_radii_data };
|
||||
ScopedCornerRadiusClip corner_clipper { context, context.painter(), backdrop_region.to_type<DevicePixels>(), border_radii_data };
|
||||
|
||||
// FIXME: 5. Draw all of element B, including its background, border, and any children elements, into T’.
|
||||
|
||||
|
|
|
@ -49,9 +49,9 @@ void ImagePaintable::paint(PaintContext& context, PaintPhase phase) const
|
|||
alt = image_element.src();
|
||||
context.painter().draw_text(enclosing_int_rect(absolute_rect()), alt, Gfx::TextAlignment::Center, computed_values().color(), Gfx::TextElision::Right);
|
||||
} else if (auto bitmap = layout_box().image_loader().bitmap(layout_box().image_loader().current_frame_index())) {
|
||||
auto image_rect = absolute_rect().to_rounded<int>();
|
||||
ScopedCornerRadiusClip corner_clip { context.painter(), image_rect, normalized_border_radii_data(ShrinkRadiiForBorders::Yes) };
|
||||
context.painter().draw_scaled_bitmap(image_rect, *bitmap, bitmap->rect(), 1.0f, to_gfx_scaling_mode(computed_values().image_rendering()));
|
||||
auto image_rect = context.rounded_device_rect(absolute_rect().to_type<CSSPixels>());
|
||||
ScopedCornerRadiusClip corner_clip { context, context.painter(), image_rect, normalized_border_radii_data(ShrinkRadiiForBorders::Yes) };
|
||||
context.painter().draw_scaled_bitmap(image_rect.to_type<int>(), *bitmap, bitmap->rect(), 1.0f, to_gfx_scaling_mode(computed_values().image_rendering()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ void InlinePaintable::paint(PaintContext& context, Painting::PaintPhase phase) c
|
|||
absolute_fragment_rect.set_width(absolute_fragment_rect.width() + extra_end_width);
|
||||
}
|
||||
|
||||
auto border_radii_data = Painting::normalized_border_radii_data(layout_node(), absolute_fragment_rect, top_left_border_radius, top_right_border_radius, bottom_right_border_radius, bottom_left_border_radius);
|
||||
auto border_radii_data = Painting::normalized_border_radii_data(layout_node(), absolute_fragment_rect.to_type<CSSPixels>(), top_left_border_radius, top_right_border_radius, bottom_right_border_radius, bottom_left_border_radius);
|
||||
Painting::paint_background(context, layout_node(), absolute_fragment_rect.to_type<CSSPixels>(), computed_values().background_color(), computed_values().image_rendering(), &computed_values().background_layers(), border_radii_data);
|
||||
|
||||
if (auto computed_box_shadow = computed_values().box_shadow(); !computed_box_shadow.is_empty()) {
|
||||
|
@ -92,7 +92,7 @@ void InlinePaintable::paint(PaintContext& context, Painting::PaintPhase phase) c
|
|||
auto containing_block_position_in_absolute_coordinates = containing_block()->paint_box()->absolute_position();
|
||||
|
||||
for_each_fragment([&](auto const& fragment, bool is_first_fragment, bool is_last_fragment) {
|
||||
Gfx::FloatRect absolute_fragment_rect { containing_block_position_in_absolute_coordinates.translated(fragment.offset()), fragment.size() };
|
||||
CSSPixelRect absolute_fragment_rect { containing_block_position_in_absolute_coordinates.translated(fragment.offset()), fragment.size() };
|
||||
|
||||
if (is_first_fragment) {
|
||||
float extra_start_width = box_model().padding.left;
|
||||
|
|
|
@ -36,8 +36,8 @@ void NestedBrowsingContextPaintable::paint(PaintContext& context, PaintPhase pha
|
|||
PaintableBox::paint(context, phase);
|
||||
|
||||
if (phase == PaintPhase::Foreground) {
|
||||
auto clip_rect = absolute_rect().to_rounded<int>();
|
||||
ScopedCornerRadiusClip corner_clip { context.painter(), clip_rect, normalized_border_radii_data(ShrinkRadiiForBorders::Yes) };
|
||||
auto clip_rect = context.rounded_device_rect(absolute_rect().to_type<CSSPixels>());
|
||||
ScopedCornerRadiusClip corner_clip { context, context.painter(), clip_rect, normalized_border_radii_data(ShrinkRadiiForBorders::Yes) };
|
||||
|
||||
auto* hosted_document = layout_box().dom_node().content_document_without_origin_check();
|
||||
if (!hosted_document)
|
||||
|
@ -49,7 +49,7 @@ void NestedBrowsingContextPaintable::paint(PaintContext& context, PaintPhase pha
|
|||
context.painter().save();
|
||||
auto old_viewport_rect = context.device_viewport_rect();
|
||||
|
||||
context.painter().add_clip_rect(clip_rect);
|
||||
context.painter().add_clip_rect(clip_rect.to_type<int>());
|
||||
context.painter().translate(absolute_x(), absolute_y());
|
||||
|
||||
context.set_device_viewport_rect({ {}, layout_box().dom_node().nested_browsing_context()->size() });
|
||||
|
|
|
@ -227,7 +227,7 @@ void PaintableBox::paint_border(PaintContext& context) const
|
|||
.bottom = computed_values().border_bottom(),
|
||||
.left = computed_values().border_left(),
|
||||
};
|
||||
paint_all_borders(context, absolute_border_box_rect(), normalized_border_radii_data(), borders_data);
|
||||
paint_all_borders(context, absolute_border_box_rect().to_type<CSSPixels>(), normalized_border_radii_data(), borders_data);
|
||||
}
|
||||
|
||||
void PaintableBox::paint_backdrop_filter(PaintContext& context) const
|
||||
|
@ -300,7 +300,8 @@ void PaintableBox::paint_box_shadow(PaintContext& context) const
|
|||
|
||||
BorderRadiiData PaintableBox::normalized_border_radii_data(ShrinkRadiiForBorders shrink) const
|
||||
{
|
||||
auto border_radius_data = Painting::normalized_border_radii_data(layout_box(), absolute_border_box_rect(),
|
||||
auto border_radius_data = Painting::normalized_border_radii_data(layout_box(),
|
||||
absolute_border_box_rect().to_type<CSSPixels>(),
|
||||
computed_values().border_top_left_radius(),
|
||||
computed_values().border_top_right_radius(),
|
||||
computed_values().border_bottom_right_radius(),
|
||||
|
@ -356,7 +357,7 @@ void PaintableBox::before_children_paint(PaintContext& context, PaintPhase phase
|
|||
if (overflow_y == CSS::Overflow::Hidden || overflow_x == CSS::Overflow::Hidden) {
|
||||
auto border_radii_data = normalized_border_radii_data(ShrinkRadiiForBorders::Yes);
|
||||
if (border_radii_data.has_any_radius()) {
|
||||
auto corner_clipper = BorderRadiusCornerClipper::create(absolute_padding_box_rect().to_rounded<int>(), border_radii_data, CornerClip::Outside, BorderRadiusCornerClipper::UseCachedBitmap::No);
|
||||
auto corner_clipper = BorderRadiusCornerClipper::create(context, absolute_padding_box_rect().to_type<DevicePixels>(), border_radii_data, CornerClip::Outside, BorderRadiusCornerClipper::UseCachedBitmap::No);
|
||||
if (corner_clipper.is_error()) {
|
||||
dbgln("Failed to create overflow border-radius corner clipper: {}", corner_clipper.error());
|
||||
return;
|
||||
|
@ -553,7 +554,7 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const
|
|||
|
||||
auto border_radii = normalized_border_radii_data(ShrinkRadiiForBorders::Yes);
|
||||
if (border_radii.has_any_radius()) {
|
||||
auto clipper = BorderRadiusCornerClipper::create(clip_box, border_radii);
|
||||
auto clipper = BorderRadiusCornerClipper::create(context, clip_box.to_type<DevicePixels>(), border_radii);
|
||||
if (!clipper.is_error()) {
|
||||
corner_clipper = clipper.release_value();
|
||||
corner_clipper->sample_under_corners(context.painter());
|
||||
|
|
|
@ -25,12 +25,12 @@ void paint_box_shadow(PaintContext& context, Gfx::IntRect const& content_rect, B
|
|||
|
||||
auto& painter = context.painter();
|
||||
|
||||
auto top_left_corner = border_radii.top_left.as_corner();
|
||||
auto top_right_corner = border_radii.top_right.as_corner();
|
||||
auto bottom_right_corner = border_radii.bottom_right.as_corner();
|
||||
auto bottom_left_corner = border_radii.bottom_left.as_corner();
|
||||
auto top_left_corner = border_radii.top_left.as_corner(context);
|
||||
auto top_right_corner = border_radii.top_right.as_corner(context);
|
||||
auto bottom_right_corner = border_radii.bottom_right.as_corner(context);
|
||||
auto bottom_left_corner = border_radii.bottom_left.as_corner(context);
|
||||
|
||||
ScopedCornerRadiusClip corner_clipper { painter, content_rect, border_radii, CornerClip::Inside };
|
||||
ScopedCornerRadiusClip corner_clipper { context, painter, content_rect.to_type<DevicePixels>(), border_radii, CornerClip::Inside };
|
||||
|
||||
// Note: Box-shadow layers are ordered front-to-back, so we paint them in reverse
|
||||
for (auto& box_shadow_data : box_shadow_layers.in_reverse()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue