diff --git a/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp b/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp index 9e07897926..f55837bce2 100644 --- a/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp +++ b/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp @@ -115,7 +115,7 @@ Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_ return border_data.color; } -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_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) { auto const& border_data = [&] { switch (edge) { @@ -243,7 +243,8 @@ void paint_border(RecordingPainter& painter, BorderEdge edge, DevicePixelRect co // If joined borders have the same color, combine them to draw together. if (ready_to_draw) { path.close_all_subpaths(); - painter.fill_path({ .path = path, .color = color, .winding_rule = Gfx::Painter::WindingRule::EvenOdd }); + Gfx::AntiAliasingPainter aa_painter(painter); + aa_painter.fill_path(path, color, Gfx::Painter::WindingRule::EvenOdd); path.clear(); } }; @@ -543,7 +544,7 @@ void paint_border(RecordingPainter& painter, BorderEdge edge, DevicePixelRect co } } -void paint_all_borders(RecordingPainter& painter, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data) +void paint_all_borders(Gfx::Painter& 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; diff --git a/Userland/Libraries/LibWeb/Painting/BorderPainting.h b/Userland/Libraries/LibWeb/Painting/BorderPainting.h index 7419be1848..e51075f7ef 100644 --- a/Userland/Libraries/LibWeb/Painting/BorderPainting.h +++ b/Userland/Libraries/LibWeb/Painting/BorderPainting.h @@ -28,8 +28,8 @@ enum class BorderEdge { // Returns OptionalNone if there is no outline to paint. Optional borders_data_for_outline(Layout::Node const&, Color outline_color, CSS::OutlineStyle outline_style, CSSPixels outline_width); -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& context, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const&); +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&); Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_data); diff --git a/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp b/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp index 102767c8e6..e50d74e2ea 100644 --- a/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp @@ -134,9 +134,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); - paint_all_borders(context.painter(), context.rounded_device_rect(borders_rect), border_radii_data.as_corners(context), outline_data->to_device_pixels(context)); + context.painter().paint_borders(context.rounded_device_rect(borders_rect), border_radii_data.as_corners(context), outline_data->to_device_pixels(context)); } else { - paint_all_borders(context.painter(), context.rounded_device_rect(borders_rect), border_radii_data.as_corners(context), borders_data.to_device_pixels(context)); + context.painter().paint_borders(context.rounded_device_rect(borders_rect), border_radii_data.as_corners(context), borders_data.to_device_pixels(context)); } return IterationDecision::Continue; diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index 8b70a016ce..a7be068614 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -246,7 +246,7 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const border_radius_data.inflate(outline_width + outline_offset_y, outline_width + outline_offset_x, outline_width + outline_offset_y, outline_width + outline_offset_x); borders_rect.inflate(outline_width + outline_offset_y, outline_width + outline_offset_x, outline_width + outline_offset_y, outline_width + outline_offset_x); - paint_all_borders(context.painter(), context.rounded_device_rect(borders_rect), border_radius_data.as_corners(context), borders_data->to_device_pixels(context)); + context.painter().paint_borders(context.rounded_device_rect(borders_rect), border_radius_data.as_corners(context), borders_data->to_device_pixels(context)); } } @@ -313,7 +313,7 @@ void PaintableBox::paint_border(PaintContext& context) const .bottom = box_model().border.bottom == 0 ? CSS::BorderData() : computed_values().border_bottom(), .left = box_model().border.left == 0 ? CSS::BorderData() : computed_values().border_left(), }; - paint_all_borders(context.painter(), context.rounded_device_rect(absolute_border_box_rect()), normalized_border_radii_data().as_corners(context), borders_data.to_device_pixels(context)); + context.painter().paint_borders(context.rounded_device_rect(absolute_border_box_rect()), normalized_border_radii_data().as_corners(context), borders_data.to_device_pixels(context)); } void PaintableBox::paint_backdrop_filter(PaintContext& context) const diff --git a/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorCPU.cpp b/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorCPU.cpp index 443e78c3fc..ed4aa8c821 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorCPU.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorCPU.cpp @@ -409,6 +409,12 @@ CommandResult PaintingCommandExecutorCPU::blit_corner_clipping(BorderRadiusCorne return CommandResult::Continue; } +CommandResult PaintingCommandExecutorCPU::paint_borders(DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data) +{ + paint_all_borders(painter(), border_rect, corner_radii, borders_data); + return CommandResult::Continue; +} + bool PaintingCommandExecutorCPU::would_be_fully_clipped_by_painter(Gfx::IntRect rect) const { return !painter().clip_rect().intersects(rect.translated(painter().translation())); diff --git a/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorCPU.h b/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorCPU.h index c1f377737e..b1a992250d 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorCPU.h +++ b/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorCPU.h @@ -44,6 +44,7 @@ public: CommandResult draw_triangle_wave(Gfx::IntPoint const& p1, Gfx::IntPoint const& p2, Color const&, int amplitude, int thickness) override; CommandResult sample_under_corners(BorderRadiusCornerClipper&) override; CommandResult blit_corner_clipping(BorderRadiusCornerClipper&) override; + CommandResult paint_borders(DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data) override; bool would_be_fully_clipped_by_painter(Gfx::IntRect) const override; diff --git a/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorGPU.cpp b/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorGPU.cpp index 6288973291..72b4acd97c 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorGPU.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorGPU.cpp @@ -220,6 +220,15 @@ CommandResult PaintingCommandExecutorGPU::blit_corner_clipping(BorderRadiusCorne return CommandResult::Continue; } +CommandResult PaintingCommandExecutorGPU::paint_borders(DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data) +{ + // FIXME + (void)border_rect; + (void)corner_radii; + (void)borders_data; + return CommandResult::Continue; +} + bool PaintingCommandExecutorGPU::would_be_fully_clipped_by_painter(Gfx::IntRect) const { // FIXME diff --git a/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorGPU.h b/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorGPU.h index cc737a36b4..e256f3f517 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorGPU.h +++ b/Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorGPU.h @@ -44,6 +44,7 @@ public: CommandResult draw_triangle_wave(Gfx::IntPoint const& p1, Gfx::IntPoint const& p2, Color const&, int amplitude, int thickness) override; CommandResult sample_under_corners(BorderRadiusCornerClipper&) override; CommandResult blit_corner_clipping(BorderRadiusCornerClipper&) override; + CommandResult paint_borders(DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data) override; bool would_be_fully_clipped_by_painter(Gfx::IntRect) const override; diff --git a/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp b/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp index bba00f79c6..c1cb7370c6 100644 --- a/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp +++ b/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp @@ -383,6 +383,11 @@ 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) +{ + push_command(PaintBorders { border_rect, corner_radii, borders_data }); +} + static Optional command_bounding_rectangle(PaintingCommand const& command) { return command.visit( @@ -512,6 +517,9 @@ void RecordingPainter::execute(PaintingCommandExecutor& executor) }, [&](BlitCornerClipping const& command) { return executor.blit_corner_clipping(command.corner_clipper); + }, + [&](PaintBorders const& command) { + return executor.paint_borders(command.border_rect, command.corner_radii, command.borders_data); }); if (result == CommandResult::SkipStackingContext) { diff --git a/Userland/Libraries/LibWeb/Painting/RecordingPainter.h b/Userland/Libraries/LibWeb/Painting/RecordingPainter.h index ff18b89cb4..29c5026325 100644 --- a/Userland/Libraries/LibWeb/Painting/RecordingPainter.h +++ b/Userland/Libraries/LibWeb/Painting/RecordingPainter.h @@ -302,6 +302,14 @@ struct BlitCornerClipping { [[nodiscard]] Gfx::IntRect bounding_rect() const; }; +struct PaintBorders { + DevicePixelRect border_rect; + CornerRadii corner_radii; + BordersDataDevicePixels borders_data; + + [[nodiscard]] Gfx::IntRect bounding_rect() const { return border_rect.to_type(); } +}; + using PaintingCommand = Variant< DrawGlyphRun, DrawText, @@ -333,7 +341,8 @@ using PaintingCommand = Variant< DrawRect, DrawTriangleWave, SampleUnderCorners, - BlitCornerClipping>; + BlitCornerClipping, + PaintBorders>; class PaintingCommandExecutor { public: @@ -370,6 +379,7 @@ public: virtual CommandResult draw_triangle_wave(Gfx::IntPoint const& p1, Gfx::IntPoint const& p2, Color const& color, int amplitude, int thickness) = 0; virtual CommandResult sample_under_corners(BorderRadiusCornerClipper&) = 0; virtual CommandResult blit_corner_clipping(BorderRadiusCornerClipper&) = 0; + virtual CommandResult paint_borders(DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data) = 0; virtual bool would_be_fully_clipped_by_painter(Gfx::IntRect) const = 0; @@ -476,6 +486,8 @@ 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); + void execute(PaintingCommandExecutor&); RecordingPainter() diff --git a/Userland/Libraries/LibWeb/Painting/TableBordersPainting.cpp b/Userland/Libraries/LibWeb/Painting/TableBordersPainting.cpp index 80850f362e..dc9367165d 100644 --- a/Userland/Libraries/LibWeb/Painting/TableBordersPainting.cpp +++ b/Userland/Libraries/LibWeb/Painting/TableBordersPainting.cpp @@ -351,7 +351,7 @@ static void paint_separate_cell_borders(PaintableBox const& cell_box, HashMaprow_index, cell_box.table_cell_coordinates()->column_index }).value(); - paint_all_borders(context.painter(), cell_rect, cell_box.normalized_border_radii_data().as_corners(context), borders_data.to_device_pixels(context)); + context.painter().paint_borders(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(), }; - paint_all_borders(context.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)); + context.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)); } } }