1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-09 03:30:46 +00:00

LibWeb: Remove PaintBorders recording painter command

`Painting::paint_all_borders()` only uses `.draw_line()` for simple
borders and `.fill_path()` for more complex cases. These are both
already supported by the `RecordingPainter` so removing this command
simplifies the painting API.

Two test changes:

css-background-clip-text: Borders are now drawn via the AA painter
(which makes them closer to how they appear in other browsers).

corner-clip-inside-scrollable: Borders removed (does not change test)
due to imperceptible sub-pixel changes.
This commit is contained in:
MacDue 2024-05-27 19:03:12 +01:00 committed by Andreas Kling
parent 0ae36b9524
commit f7bf14605c
16 changed files with 12 additions and 90 deletions

View File

@ -8,7 +8,6 @@
.box {
width: 100px;
height: 100px;
border: 5px solid black;
border-radius: 50%;
overflow: hidden;
box-sizing: border-box;

View File

@ -3,7 +3,6 @@
.box {
width: 100px;
height: 100px;
border: 5px solid black;
border-radius: 50%;
overflow: hidden;
box-sizing: border-box;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 KiB

After

Width:  |  Height:  |  Size: 180 KiB

View File

@ -61,7 +61,7 @@ Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_
return border_data.color;
}
void paint_border(Gfx::Painter& painter, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::Path& path, bool last)
void paint_border(RecordingPainter& painter, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::Path& path, bool last)
{
auto const& border_data = [&] {
switch (edge) {
@ -189,8 +189,9 @@ void paint_border(Gfx::Painter& painter, BorderEdge edge, DevicePixelRect const&
// If joined borders have the same color, combine them to draw together.
if (ready_to_draw) {
path.close_all_subpaths();
Gfx::AntiAliasingPainter aa_painter(painter);
aa_painter.fill_path(path, color, Gfx::Painter::WindingRule::EvenOdd);
painter.fill_path({ .path = path,
.color = color,
.winding_rule = Gfx::Painter::WindingRule::EvenOdd });
path.clear();
}
};
@ -490,7 +491,7 @@ void paint_border(Gfx::Painter& painter, BorderEdge edge, DevicePixelRect const&
}
}
void paint_all_borders(Gfx::Painter& painter, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data)
void paint_all_borders(RecordingPainter& painter, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels 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;

View File

@ -26,8 +26,8 @@ enum class BorderEdge {
// Returns OptionalNone if there is no outline to paint.
Optional<BordersData> borders_data_for_outline(Layout::Node const&, Color outline_color, CSS::OutlineStyle outline_style, CSSPixels outline_width);
void paint_border(Gfx::Painter& painter, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::Path& path, bool last);
void paint_all_borders(Gfx::Painter& painter, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const&);
void paint_border(RecordingPainter& painter, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::Path& path, bool last);
void paint_all_borders(RecordingPainter& painter, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const&);
Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_data);

View File

@ -379,19 +379,6 @@ struct BlitCornerClipping {
void translate_by(Gfx::IntPoint const& offset) { border_rect.translate_by(offset); }
};
struct PaintBorders {
DevicePixelRect border_rect;
CornerRadii corner_radii;
BordersDataDevicePixels borders_data;
[[nodiscard]] Gfx::IntRect bounding_rect() const { return border_rect.to_type<int>(); }
void translate_by(Gfx::IntPoint const& offset)
{
border_rect.translate_by(offset.to_type<DevicePixels>());
}
};
using Command = Variant<
DrawGlyphRun,
DrawText,
@ -421,7 +408,6 @@ using Command = Variant<
DrawRect,
DrawTriangleWave,
SampleUnderCorners,
BlitCornerClipping,
PaintBorders>;
BlitCornerClipping>;
}

View File

@ -473,12 +473,6 @@ CommandResult CommandExecutorCPU::blit_corner_clipping(BlitCornerClipping const&
return CommandResult::Continue;
}
CommandResult CommandExecutorCPU::paint_borders(PaintBorders const& command)
{
paint_all_borders(painter(), command.border_rect, command.corner_radii, command.borders_data);
return CommandResult::Continue;
}
bool CommandExecutorCPU::would_be_fully_clipped_by_painter(Gfx::IntRect rect) const
{
return !painter().clip_rect().intersects(rect.translated(painter().translation()));

View File

@ -42,7 +42,6 @@ public:
CommandResult draw_triangle_wave(DrawTriangleWave const&) override;
CommandResult sample_under_corners(SampleUnderCorners const&) override;
CommandResult blit_corner_clipping(BlitCornerClipping const&) override;
CommandResult paint_borders(PaintBorders const&) override;
bool would_be_fully_clipped_by_painter(Gfx::IntRect) const override;

View File

@ -378,50 +378,6 @@ CommandResult CommandExecutorGPU::blit_corner_clipping(BlitCornerClipping const&
return CommandResult::Continue;
}
CommandResult CommandExecutorGPU::paint_borders(PaintBorders const& command)
{
// FIXME: Add support for corner radiuses
auto const& border_rect = command.border_rect;
auto const& borders_data = command.borders_data;
Gfx::IntRect top_border_rect = {
border_rect.x(),
border_rect.y(),
border_rect.width(),
borders_data.top.width
};
Gfx::IntRect right_border_rect = {
border_rect.x() + (border_rect.width() - borders_data.right.width),
border_rect.y(),
borders_data.right.width,
border_rect.height()
};
Gfx::IntRect bottom_border_rect = {
border_rect.x(),
border_rect.y() + (border_rect.height() - borders_data.bottom.width),
border_rect.width(),
borders_data.bottom.width
};
Gfx::IntRect left_border_rect = {
border_rect.x(),
border_rect.y(),
borders_data.left.width,
border_rect.height()
};
if (borders_data.top.width > 0)
painter().fill_rect(top_border_rect, borders_data.top.color);
if (borders_data.right.width > 0)
painter().fill_rect(right_border_rect, borders_data.right.color);
if (borders_data.bottom.width > 0)
painter().fill_rect(bottom_border_rect, borders_data.bottom.color);
if (borders_data.left.width > 0)
painter().fill_rect(left_border_rect, borders_data.left.color);
return CommandResult::Continue;
}
bool CommandExecutorGPU::would_be_fully_clipped_by_painter(Gfx::IntRect rect) const
{
auto translation = painter().transform().translation().to_type<int>();

View File

@ -43,7 +43,6 @@ public:
CommandResult draw_triangle_wave(DrawTriangleWave const&) override;
CommandResult sample_under_corners(SampleUnderCorners const&) override;
CommandResult blit_corner_clipping(BlitCornerClipping const&) override;
CommandResult paint_borders(PaintBorders const&) override;
bool would_be_fully_clipped_by_painter(Gfx::IntRect) const override;

View File

@ -176,7 +176,6 @@ void CommandList::execute(CommandExecutor& executor)
else HANDLE_COMMAND(DrawTriangleWave, draw_triangle_wave)
else HANDLE_COMMAND(SampleUnderCorners, sample_under_corners)
else HANDLE_COMMAND(BlitCornerClipping, blit_corner_clipping)
else HANDLE_COMMAND(PaintBorders, paint_borders)
else VERIFY_NOT_REACHED();
// clang-format on

View File

@ -76,7 +76,6 @@ public:
virtual CommandResult draw_triangle_wave(DrawTriangleWave const&) = 0;
virtual CommandResult sample_under_corners(SampleUnderCorners const&) = 0;
virtual CommandResult blit_corner_clipping(BlitCornerClipping const&) = 0;
virtual CommandResult paint_borders(PaintBorders const&) = 0;
virtual bool would_be_fully_clipped_by_painter(Gfx::IntRect) const = 0;
virtual bool needs_prepare_glyphs_texture() const { return false; }
virtual void prepare_glyph_texture(HashMap<Gfx::Font const*, HashTable<u32>> const& unique_glyphs) = 0;

View File

@ -141,9 +141,9 @@ void InlinePaintable::paint(PaintContext& context, PaintPhase phase) const
border_radii_data.inflate(outline_data->top.width + outline_offset_y, outline_data->right.width + outline_offset_x, outline_data->bottom.width + outline_offset_y, outline_data->left.width + outline_offset_x);
borders_rect.inflate(outline_data->top.width + outline_offset_y, outline_data->right.width + outline_offset_x, outline_data->bottom.width + outline_offset_y, outline_data->left.width + outline_offset_x);
context.recording_painter().paint_borders(context.rounded_device_rect(borders_rect), border_radii_data.as_corners(context), outline_data->to_device_pixels(context));
paint_all_borders(context.recording_painter(), context.rounded_device_rect(borders_rect), border_radii_data.as_corners(context), outline_data->to_device_pixels(context));
} else {
context.recording_painter().paint_borders(context.rounded_device_rect(borders_rect), border_radii_data.as_corners(context), borders_data.to_device_pixels(context));
paint_all_borders(context.recording_painter(), context.rounded_device_rect(borders_rect), border_radii_data.as_corners(context), borders_data.to_device_pixels(context));
}
return IterationDecision::Continue;

View File

@ -419,11 +419,4 @@ void RecordingPainter::draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2
.thickness = thickness });
}
void RecordingPainter::paint_borders(DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data)
{
if (borders_data.top.width == 0 && borders_data.right.width == 0 && borders_data.bottom.width == 0 && borders_data.left.width == 0)
return;
append(PaintBorders { border_rect, corner_radii, borders_data });
}
}

View File

@ -141,8 +141,6 @@ public:
void draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2, Color color, int amplitude, int thickness);
void paint_borders(DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data);
RecordingPainter(CommandList& commands_list);
~RecordingPainter();

View File

@ -351,7 +351,7 @@ static void paint_separate_cell_borders(PaintableBox const& cell_box, HashMap<Ce
.left = cell_box.box_model().border.left == 0 ? CSS::BorderData() : cell_box.computed_values().border_left(),
};
auto cell_rect = cell_coordinates_to_device_rect.get({ cell_box.table_cell_coordinates()->row_index, cell_box.table_cell_coordinates()->column_index }).value();
context.recording_painter().paint_borders(cell_rect, cell_box.normalized_border_radii_data().as_corners(context), borders_data.to_device_pixels(context));
paint_all_borders(context.recording_painter(), cell_rect, cell_box.normalized_border_radii_data().as_corners(context), borders_data.to_device_pixels(context));
}
void paint_table_borders(PaintContext& context, PaintableBox const& table_paintable)
@ -436,7 +436,7 @@ void paint_table_borders(PaintContext& context, PaintableBox const& table_painta
.bottom = cell_box.box_model().border.bottom == 0 ? CSS::BorderData() : cell_box.computed_values().border_bottom(),
.left = cell_box.box_model().border.left == 0 ? CSS::BorderData() : cell_box.computed_values().border_left(),
};
context.recording_painter().paint_borders(context.rounded_device_rect(cell_box.absolute_border_box_rect()), cell_box.normalized_border_radii_data().as_corners(context), borders_data.to_device_pixels(context));
paint_all_borders(context.recording_painter(), context.rounded_device_rect(cell_box.absolute_border_box_rect()), cell_box.normalized_border_radii_data().as_corners(context), borders_data.to_device_pixels(context));
}
}
}