mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-21 18:15:58 +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:
parent
0ae36b9524
commit
f7bf14605c
|
@ -8,7 +8,6 @@
|
||||||
.box {
|
.box {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
border: 5px solid black;
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
.box {
|
.box {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
border: 5px solid black;
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 180 KiB |
|
@ -61,7 +61,7 @@ Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_
|
||||||
return border_data.color;
|
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 = [&] {
|
auto const& border_data = [&] {
|
||||||
switch (edge) {
|
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 joined borders have the same color, combine them to draw together.
|
||||||
if (ready_to_draw) {
|
if (ready_to_draw) {
|
||||||
path.close_all_subpaths();
|
path.close_all_subpaths();
|
||||||
Gfx::AntiAliasingPainter aa_painter(painter);
|
painter.fill_path({ .path = path,
|
||||||
aa_painter.fill_path(path, color, Gfx::Painter::WindingRule::EvenOdd);
|
.color = color,
|
||||||
|
.winding_rule = Gfx::Painter::WindingRule::EvenOdd });
|
||||||
path.clear();
|
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)
|
if (borders_data.top.width <= 0 && borders_data.right.width <= 0 && borders_data.left.width <= 0 && borders_data.bottom.width <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -26,8 +26,8 @@ enum class BorderEdge {
|
||||||
// Returns OptionalNone if there is no outline to paint.
|
// 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);
|
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_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(Gfx::Painter& painter, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const&);
|
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);
|
Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_data);
|
||||||
|
|
||||||
|
|
|
@ -379,19 +379,6 @@ struct BlitCornerClipping {
|
||||||
void translate_by(Gfx::IntPoint const& offset) { border_rect.translate_by(offset); }
|
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<
|
using Command = Variant<
|
||||||
DrawGlyphRun,
|
DrawGlyphRun,
|
||||||
DrawText,
|
DrawText,
|
||||||
|
@ -421,7 +408,6 @@ using Command = Variant<
|
||||||
DrawRect,
|
DrawRect,
|
||||||
DrawTriangleWave,
|
DrawTriangleWave,
|
||||||
SampleUnderCorners,
|
SampleUnderCorners,
|
||||||
BlitCornerClipping,
|
BlitCornerClipping>;
|
||||||
PaintBorders>;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,12 +473,6 @@ CommandResult CommandExecutorCPU::blit_corner_clipping(BlitCornerClipping const&
|
||||||
return CommandResult::Continue;
|
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
|
bool CommandExecutorCPU::would_be_fully_clipped_by_painter(Gfx::IntRect rect) const
|
||||||
{
|
{
|
||||||
return !painter().clip_rect().intersects(rect.translated(painter().translation()));
|
return !painter().clip_rect().intersects(rect.translated(painter().translation()));
|
||||||
|
|
|
@ -42,7 +42,6 @@ public:
|
||||||
CommandResult draw_triangle_wave(DrawTriangleWave const&) override;
|
CommandResult draw_triangle_wave(DrawTriangleWave const&) override;
|
||||||
CommandResult sample_under_corners(SampleUnderCorners const&) override;
|
CommandResult sample_under_corners(SampleUnderCorners const&) override;
|
||||||
CommandResult blit_corner_clipping(BlitCornerClipping 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;
|
bool would_be_fully_clipped_by_painter(Gfx::IntRect) const override;
|
||||||
|
|
||||||
|
|
|
@ -378,50 +378,6 @@ CommandResult CommandExecutorGPU::blit_corner_clipping(BlitCornerClipping const&
|
||||||
return CommandResult::Continue;
|
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
|
bool CommandExecutorGPU::would_be_fully_clipped_by_painter(Gfx::IntRect rect) const
|
||||||
{
|
{
|
||||||
auto translation = painter().transform().translation().to_type<int>();
|
auto translation = painter().transform().translation().to_type<int>();
|
||||||
|
|
|
@ -43,7 +43,6 @@ public:
|
||||||
CommandResult draw_triangle_wave(DrawTriangleWave const&) override;
|
CommandResult draw_triangle_wave(DrawTriangleWave const&) override;
|
||||||
CommandResult sample_under_corners(SampleUnderCorners const&) override;
|
CommandResult sample_under_corners(SampleUnderCorners const&) override;
|
||||||
CommandResult blit_corner_clipping(BlitCornerClipping 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;
|
bool would_be_fully_clipped_by_painter(Gfx::IntRect) const override;
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,6 @@ void CommandList::execute(CommandExecutor& executor)
|
||||||
else HANDLE_COMMAND(DrawTriangleWave, draw_triangle_wave)
|
else HANDLE_COMMAND(DrawTriangleWave, draw_triangle_wave)
|
||||||
else HANDLE_COMMAND(SampleUnderCorners, sample_under_corners)
|
else HANDLE_COMMAND(SampleUnderCorners, sample_under_corners)
|
||||||
else HANDLE_COMMAND(BlitCornerClipping, blit_corner_clipping)
|
else HANDLE_COMMAND(BlitCornerClipping, blit_corner_clipping)
|
||||||
else HANDLE_COMMAND(PaintBorders, paint_borders)
|
|
||||||
else VERIFY_NOT_REACHED();
|
else VERIFY_NOT_REACHED();
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,6 @@ public:
|
||||||
virtual CommandResult draw_triangle_wave(DrawTriangleWave const&) = 0;
|
virtual CommandResult draw_triangle_wave(DrawTriangleWave const&) = 0;
|
||||||
virtual CommandResult sample_under_corners(SampleUnderCorners const&) = 0;
|
virtual CommandResult sample_under_corners(SampleUnderCorners const&) = 0;
|
||||||
virtual CommandResult blit_corner_clipping(BlitCornerClipping 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 would_be_fully_clipped_by_painter(Gfx::IntRect) const = 0;
|
||||||
virtual bool needs_prepare_glyphs_texture() const { return false; }
|
virtual bool needs_prepare_glyphs_texture() const { return false; }
|
||||||
virtual void prepare_glyph_texture(HashMap<Gfx::Font const*, HashTable<u32>> const& unique_glyphs) = 0;
|
virtual void prepare_glyph_texture(HashMap<Gfx::Font const*, HashTable<u32>> const& unique_glyphs) = 0;
|
||||||
|
|
|
@ -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);
|
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);
|
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 {
|
} 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;
|
return IterationDecision::Continue;
|
||||||
|
|
|
@ -419,11 +419,4 @@ void RecordingPainter::draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2
|
||||||
.thickness = thickness });
|
.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 });
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,8 +141,6 @@ public:
|
||||||
|
|
||||||
void draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2, Color color, int amplitude, int thickness);
|
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(CommandList& commands_list);
|
||||||
~RecordingPainter();
|
~RecordingPainter();
|
||||||
|
|
||||||
|
|
|
@ -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(),
|
.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();
|
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)
|
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(),
|
.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(),
|
.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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue