diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index df16526a96..70cbf5deda 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -482,6 +482,7 @@ set(SOURCES Painting/BorderRadiiData.cpp Painting/BorderPainting.cpp Painting/BorderRadiusCornerClipper.cpp + Painting/BordersData.cpp Painting/ButtonPaintable.cpp Painting/CanvasPaintable.cpp Painting/CheckBoxPaintable.cpp diff --git a/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp b/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp index cd71d85fab..9e07897926 100644 --- a/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp +++ b/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp @@ -85,7 +85,7 @@ static Color dark_color_for_inset_and_outset(Color const& color) return Color::from_hsv({ hsv.hue, hsv.saturation, hsv.value - dark_light_absolute_value_difference }); } -Gfx::Color border_color(BorderEdge edge, BordersData const& borders_data) +Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_data) { auto const& border_data = [&] { switch (edge) { @@ -115,7 +115,7 @@ Gfx::Color border_color(BorderEdge edge, BordersData const& borders_data) return border_data.color; } -void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersData 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) { @@ -130,13 +130,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& } }(); - CSSPixels width = border_data.width; - if (width <= 0) + if (border_data.width <= 0) return; auto color = border_color(edge, borders_data); auto border_style = border_data.line_style; - auto device_pixel_width = context.rounded_device_pixels(width); struct Points { DevicePixelPoint p1; @@ -183,27 +181,27 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& auto [p1, p2] = points_for_edge(edge, rect); switch (edge) { case BorderEdge::Top: - p1.translate_by(device_pixel_width / 2, device_pixel_width / 2); - p2.translate_by(-device_pixel_width / 2, device_pixel_width / 2); + p1.translate_by(border_data.width / 2, border_data.width / 2); + p2.translate_by(-border_data.width / 2, border_data.width / 2); break; case BorderEdge::Right: - p1.translate_by(-device_pixel_width / 2, device_pixel_width / 2); - p2.translate_by(-device_pixel_width / 2, -device_pixel_width / 2); + p1.translate_by(-border_data.width / 2, border_data.width / 2); + p2.translate_by(-border_data.width / 2, -border_data.width / 2); break; case BorderEdge::Bottom: - p1.translate_by(device_pixel_width / 2, -device_pixel_width / 2); - p2.translate_by(-device_pixel_width / 2, -device_pixel_width / 2); + p1.translate_by(border_data.width / 2, -border_data.width / 2); + p2.translate_by(-border_data.width / 2, -border_data.width / 2); break; case BorderEdge::Left: - p1.translate_by(device_pixel_width / 2, device_pixel_width / 2); - p2.translate_by(device_pixel_width / 2, -device_pixel_width / 2); + p1.translate_by(border_data.width / 2, border_data.width / 2); + p2.translate_by(border_data.width / 2, -border_data.width / 2); break; } if (border_style == CSS::LineStyle::Dotted) { - context.painter().draw_line(p1.to_type(), p2.to_type(), color, device_pixel_width.value(), gfx_line_style); + painter.draw_line(p1.to_type(), p2.to_type(), color, border_data.width.value(), gfx_line_style); return; } - context.painter().draw_line(p1.to_type(), p2.to_type(), color, device_pixel_width.value(), gfx_line_style); + painter.draw_line(p1.to_type(), p2.to_type(), color, border_data.width.value(), gfx_line_style); return; } @@ -245,7 +243,7 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& // If joined borders have the same color, combine them to draw together. if (ready_to_draw) { path.close_all_subpaths(); - context.painter().fill_path({ .path = path, .color = color, .winding_rule = Gfx::Painter::WindingRule::EvenOdd }); + painter.fill_path({ .path = path, .color = color, .winding_rule = Gfx::Painter::WindingRule::EvenOdd }); path.clear(); } }; @@ -285,10 +283,10 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& */ switch (edge) { case BorderEdge::Top: { - auto joined_border_width = context.enclosing_device_pixels(borders_data.left.width); - auto opposite_joined_border_width = context.enclosing_device_pixels(borders_data.right.width); - bool joined_corner_has_inner_corner = device_pixel_width < radius.vertical_radius && joined_border_width < radius.horizontal_radius; - bool opposite_joined_corner_has_inner_corner = device_pixel_width < opposite_radius.vertical_radius && opposite_joined_border_width < opposite_radius.horizontal_radius; + auto joined_border_width = borders_data.left.width; + auto opposite_joined_border_width = borders_data.right.width; + bool joined_corner_has_inner_corner = border_data.width < radius.vertical_radius && joined_border_width < radius.horizontal_radius; + bool opposite_joined_corner_has_inner_corner = border_data.width < opposite_radius.vertical_radius && opposite_joined_border_width < opposite_radius.horizontal_radius; Gfx::FloatPoint joined_corner_endpoint_offset; Gfx::FloatPoint opposite_joined_border_corner_offset; @@ -310,11 +308,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& if (joined_corner_has_inner_corner) { Gfx::FloatPoint midpoint = compute_midpoint( radius.horizontal_radius - joined_border_width.value(), - radius.vertical_radius - device_pixel_width.value(), + radius.vertical_radius - border_data.width.value(), joined_border_width.value()); Gfx::FloatPoint inner_corner_endpoint_offset = Gfx::FloatPoint( -midpoint.x(), - radius.vertical_radius - device_pixel_width.value() - midpoint.y()); + radius.vertical_radius - border_data.width.value() - midpoint.y()); points.append(Gfx::FloatPoint(rect.bottom_left().to_type()) + inner_corner_endpoint_offset); points.append(Gfx::FloatPoint(rect.bottom_left().to_type())); } else { @@ -327,11 +325,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& if (opposite_joined_corner_has_inner_corner) { Gfx::FloatPoint midpoint = compute_midpoint( opposite_radius.horizontal_radius - opposite_joined_border_width.value(), - opposite_radius.vertical_radius - device_pixel_width.value(), + opposite_radius.vertical_radius - border_data.width.value(), opposite_joined_border_width.value()); Gfx::FloatPoint inner_corner_endpoint_offset = Gfx::FloatPoint( midpoint.x(), - opposite_radius.vertical_radius - device_pixel_width.value() - midpoint.y()); + opposite_radius.vertical_radius - border_data.width.value() - midpoint.y()); points.append(Gfx::FloatPoint(rect.bottom_right().to_type())); points.append(Gfx::FloatPoint(rect.bottom_right().to_type()) + inner_corner_endpoint_offset); } else { @@ -348,16 +346,16 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& points, joined_corner_has_inner_corner, opposite_joined_corner_has_inner_corner, - Gfx::FloatSize(joined_border_width.value(), device_pixel_width.value()), - Gfx::FloatSize(opposite_joined_border_width.value(), device_pixel_width.value()), + Gfx::FloatSize(joined_border_width.value(), border_data.width.value()), + Gfx::FloatSize(opposite_joined_border_width.value(), border_data.width.value()), last || color != border_color(BorderEdge::Right, borders_data)); break; } case BorderEdge::Right: { - auto joined_border_width = context.enclosing_device_pixels(borders_data.top.width); - auto opposite_joined_border_width = context.enclosing_device_pixels(borders_data.bottom.width); - bool joined_corner_has_inner_corner = device_pixel_width < radius.horizontal_radius && joined_border_width < radius.vertical_radius; - bool opposite_joined_corner_has_inner_corner = device_pixel_width < opposite_radius.horizontal_radius && opposite_joined_border_width < opposite_radius.vertical_radius; + auto joined_border_width = borders_data.top.width; + auto opposite_joined_border_width = borders_data.bottom.width; + bool joined_corner_has_inner_corner = border_data.width < radius.horizontal_radius && joined_border_width < radius.vertical_radius; + bool opposite_joined_corner_has_inner_corner = border_data.width < opposite_radius.horizontal_radius && opposite_joined_border_width < opposite_radius.vertical_radius; Gfx::FloatPoint joined_corner_endpoint_offset; Gfx::FloatPoint opposite_joined_border_corner_offset; @@ -378,11 +376,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& if (joined_corner_has_inner_corner) { auto midpoint = compute_midpoint( - radius.horizontal_radius - device_pixel_width.value(), + radius.horizontal_radius - border_data.width.value(), radius.vertical_radius - joined_border_width.value(), joined_border_width.value()); Gfx::FloatPoint inner_corner = Gfx::FloatPoint( - -(radius.horizontal_radius - midpoint.x() - device_pixel_width.value()), + -(radius.horizontal_radius - midpoint.x() - border_data.width.value()), -midpoint.y()); points.append(Gfx::FloatPoint(rect.top_left().to_type()) + inner_corner); points.append(Gfx::FloatPoint(rect.top_left().to_type())); @@ -393,11 +391,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& if (opposite_joined_corner_has_inner_corner) { auto midpoint = compute_midpoint( - opposite_radius.horizontal_radius - device_pixel_width.value(), + opposite_radius.horizontal_radius - border_data.width.value(), opposite_radius.vertical_radius - opposite_joined_border_width.value(), opposite_joined_border_width.value()); Gfx::FloatPoint inner_corner = Gfx::FloatPoint( - -(opposite_radius.horizontal_radius - midpoint.x() - device_pixel_width.value()), + -(opposite_radius.horizontal_radius - midpoint.x() - border_data.width.value()), midpoint.y()); points.append(Gfx::FloatPoint(rect.bottom_left().to_type())); points.append(Gfx::FloatPoint(rect.bottom_left().to_type()) + inner_corner); @@ -413,16 +411,16 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& points, joined_corner_has_inner_corner, opposite_joined_corner_has_inner_corner, - Gfx::FloatSize(device_pixel_width.value(), joined_border_width.value()), - Gfx::FloatSize(device_pixel_width.value(), opposite_joined_border_width.value()), + Gfx::FloatSize(border_data.width.value(), joined_border_width.value()), + Gfx::FloatSize(border_data.width.value(), opposite_joined_border_width.value()), last || color != border_color(BorderEdge::Bottom, borders_data)); break; } case BorderEdge::Bottom: { - auto joined_border_width = context.enclosing_device_pixels(borders_data.right.width); - auto opposite_joined_border_width = context.enclosing_device_pixels(borders_data.left.width); - bool joined_corner_has_inner_corner = device_pixel_width < radius.vertical_radius && joined_border_width < radius.horizontal_radius; - bool opposite_joined_corner_has_inner_corner = device_pixel_width < opposite_radius.vertical_radius && opposite_joined_border_width < opposite_radius.horizontal_radius; + auto joined_border_width = borders_data.right.width; + auto opposite_joined_border_width = borders_data.left.width; + bool joined_corner_has_inner_corner = border_data.width < radius.vertical_radius && joined_border_width < radius.horizontal_radius; + bool opposite_joined_corner_has_inner_corner = border_data.width < opposite_radius.vertical_radius && opposite_joined_border_width < opposite_radius.horizontal_radius; Gfx::FloatPoint joined_corner_endpoint_offset; Gfx::FloatPoint opposite_joined_border_corner_offset; @@ -444,9 +442,9 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& if (joined_corner_has_inner_corner) { auto midpoint = compute_midpoint( radius.horizontal_radius - joined_border_width.value(), - radius.vertical_radius - device_pixel_width.value(), + radius.vertical_radius - border_data.width.value(), joined_border_width.value()); - Gfx::FloatPoint inner_corner = Gfx::FloatPoint(midpoint.x(), -(radius.vertical_radius - midpoint.y() - device_pixel_width.value())); + Gfx::FloatPoint inner_corner = Gfx::FloatPoint(midpoint.x(), -(radius.vertical_radius - midpoint.y() - border_data.width.value())); points.append(Gfx::FloatPoint(rect.top_right().to_type()) + inner_corner); points.append(Gfx::FloatPoint(rect.top_right().to_type())); } else { @@ -457,11 +455,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& if (opposite_joined_corner_has_inner_corner) { auto midpoint = compute_midpoint( opposite_radius.horizontal_radius - opposite_joined_border_width.value(), - opposite_radius.vertical_radius - device_pixel_width.value(), + opposite_radius.vertical_radius - border_data.width.value(), opposite_joined_border_width.value()); Gfx::FloatPoint inner_corner = Gfx::FloatPoint( -midpoint.x(), - -(opposite_radius.vertical_radius - midpoint.y() - device_pixel_width.value())); + -(opposite_radius.vertical_radius - midpoint.y() - border_data.width.value())); points.append(Gfx::FloatPoint(rect.top_left().to_type())); points.append(Gfx::FloatPoint(rect.top_left().to_type()) + inner_corner); } else { @@ -475,16 +473,16 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& points, joined_corner_has_inner_corner, opposite_joined_corner_has_inner_corner, - Gfx::FloatSize(joined_border_width.value(), device_pixel_width.value()), - Gfx::FloatSize(opposite_joined_border_width.value(), device_pixel_width.value()), + Gfx::FloatSize(joined_border_width.value(), border_data.width.value()), + Gfx::FloatSize(opposite_joined_border_width.value(), border_data.width.value()), last || color != border_color(BorderEdge::Left, borders_data)); break; } case BorderEdge::Left: { - auto joined_border_width = context.enclosing_device_pixels(borders_data.bottom.width); - auto opposite_joined_border_width = context.enclosing_device_pixels(borders_data.top.width); - bool joined_corner_has_inner_corner = device_pixel_width < radius.horizontal_radius && joined_border_width < radius.vertical_radius; - bool opposite_joined_corner_has_inner_corner = device_pixel_width < opposite_radius.horizontal_radius && opposite_joined_border_width < opposite_radius.vertical_radius; + auto joined_border_width = borders_data.bottom.width; + auto opposite_joined_border_width = borders_data.top.width; + bool joined_corner_has_inner_corner = border_data.width < radius.horizontal_radius && joined_border_width < radius.vertical_radius; + bool opposite_joined_corner_has_inner_corner = border_data.width < opposite_radius.horizontal_radius && opposite_joined_border_width < opposite_radius.vertical_radius; Gfx::FloatPoint joined_corner_endpoint_offset; Gfx::FloatPoint opposite_joined_border_corner_offset; @@ -505,10 +503,10 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& if (joined_corner_has_inner_corner) { auto midpoint = compute_midpoint( - radius.horizontal_radius - device_pixel_width.value(), + radius.horizontal_radius - border_data.width.value(), radius.vertical_radius - joined_border_width.value(), joined_border_width.value()); - Gfx::FloatPoint inner_corner = Gfx::FloatPoint(radius.horizontal_radius - device_pixel_width.value() - midpoint.x(), midpoint.y()); + Gfx::FloatPoint inner_corner = Gfx::FloatPoint(radius.horizontal_radius - border_data.width.value() - midpoint.x(), midpoint.y()); points.append(Gfx::FloatPoint(rect.bottom_right().to_type()) + inner_corner); points.append(Gfx::FloatPoint(rect.bottom_right().to_type())); } else { @@ -518,11 +516,11 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& if (opposite_joined_corner_has_inner_corner) { auto midpoint = compute_midpoint( - opposite_radius.horizontal_radius - device_pixel_width.value(), + opposite_radius.horizontal_radius - border_data.width.value(), opposite_radius.vertical_radius - opposite_joined_border_width.value(), opposite_joined_border_width.value()); Gfx::FloatPoint inner_corner = Gfx::FloatPoint( - opposite_radius.horizontal_radius - device_pixel_width.value() - midpoint.x(), + opposite_radius.horizontal_radius - border_data.width.value() - midpoint.x(), -midpoint.y()); points.append(Gfx::FloatPoint(rect.top_right().to_type())); points.append(Gfx::FloatPoint(rect.top_right().to_type()) + inner_corner); @@ -537,23 +535,23 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const& points, joined_corner_has_inner_corner, opposite_joined_corner_has_inner_corner, - Gfx::FloatSize(device_pixel_width.value(), joined_border_width.value()), - Gfx::FloatSize(device_pixel_width.value(), opposite_joined_border_width.value()), + Gfx::FloatSize(border_data.width.value(), joined_border_width.value()), + Gfx::FloatSize(border_data.width.value(), opposite_joined_border_width.value()), last || color != border_color(BorderEdge::Top, borders_data)); break; } } } -void paint_all_borders(PaintContext& context, DevicePixelRect const& border_rect, BorderRadiiData const& border_radii_data, BordersData 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; - 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); + auto top_left = corner_radii.top_left; + auto top_right = corner_radii.top_right; + auto bottom_right = corner_radii.bottom_right; + auto bottom_left = corner_radii.bottom_left; // Disable border radii if the corresponding borders don't exist: if (borders_data.bottom.width <= 0 && borders_data.left.width <= 0) @@ -569,24 +567,24 @@ void paint_all_borders(PaintContext& context, DevicePixelRect const& border_rect border_rect.x() + top_left.horizontal_radius, border_rect.y(), border_rect.width() - top_left.horizontal_radius - top_right.horizontal_radius, - context.enclosing_device_pixels(borders_data.top.width) + borders_data.top.width }; DevicePixelRect right_border_rect = { - border_rect.x() + (border_rect.width() - context.enclosing_device_pixels(borders_data.right.width)), + border_rect.x() + (border_rect.width() - borders_data.right.width), border_rect.y() + top_right.vertical_radius, - context.enclosing_device_pixels(borders_data.right.width), + borders_data.right.width, border_rect.height() - top_right.vertical_radius - bottom_right.vertical_radius }; DevicePixelRect bottom_border_rect = { border_rect.x() + bottom_left.horizontal_radius, - border_rect.y() + (border_rect.height() - context.enclosing_device_pixels(borders_data.bottom.width)), + border_rect.y() + (border_rect.height() - borders_data.bottom.width), border_rect.width() - bottom_left.horizontal_radius - bottom_right.horizontal_radius, - context.enclosing_device_pixels(borders_data.bottom.width) + borders_data.bottom.width }; DevicePixelRect left_border_rect = { border_rect.x(), border_rect.y() + top_left.vertical_radius, - context.enclosing_device_pixels(borders_data.left.width), + borders_data.left.width, border_rect.height() - top_left.vertical_radius - bottom_left.vertical_radius }; @@ -611,16 +609,16 @@ void paint_all_borders(PaintContext& context, DevicePixelRect const& border_rect for (BorderEdge edge : borders) { switch (edge) { case BorderEdge::Top: - paint_border(context, BorderEdge::Top, top_border_rect, top_left, top_right, borders_data, path, edge == borders.last()); + paint_border(painter, BorderEdge::Top, top_border_rect, top_left, top_right, borders_data, path, edge == borders.last()); break; case BorderEdge::Right: - paint_border(context, BorderEdge::Right, right_border_rect, top_right, bottom_right, borders_data, path, edge == borders.last()); + paint_border(painter, BorderEdge::Right, right_border_rect, top_right, bottom_right, borders_data, path, edge == borders.last()); break; case BorderEdge::Bottom: - paint_border(context, BorderEdge::Bottom, bottom_border_rect, bottom_right, bottom_left, borders_data, path, edge == borders.last()); + paint_border(painter, BorderEdge::Bottom, bottom_border_rect, bottom_right, bottom_left, borders_data, path, edge == borders.last()); break; case BorderEdge::Left: - paint_border(context, BorderEdge::Left, left_border_rect, bottom_left, top_left, borders_data, path, edge == borders.last()); + paint_border(painter, BorderEdge::Left, left_border_rect, bottom_left, top_left, borders_data, path, edge == borders.last()); break; default: VERIFY_NOT_REACHED(); diff --git a/Userland/Libraries/LibWeb/Painting/BorderPainting.h b/Userland/Libraries/LibWeb/Painting/BorderPainting.h index 494a658430..7419be1848 100644 --- a/Userland/Libraries/LibWeb/Painting/BorderPainting.h +++ b/Userland/Libraries/LibWeb/Painting/BorderPainting.h @@ -28,9 +28,9 @@ 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(PaintContext& context, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersData const& borders_data, Gfx::Path& path, bool last); -void paint_all_borders(PaintContext& context, DevicePixelRect const& border_rect, BorderRadiiData const& border_radii_data, BordersData 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& context, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const&); -Gfx::Color border_color(BorderEdge edge, BordersData const& borders_data); +Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_data); } diff --git a/Userland/Libraries/LibWeb/Painting/BorderRadiiData.h b/Userland/Libraries/LibWeb/Painting/BorderRadiiData.h index 8c0e327d60..5aa7a3e020 100644 --- a/Userland/Libraries/LibWeb/Painting/BorderRadiiData.h +++ b/Userland/Libraries/LibWeb/Painting/BorderRadiiData.h @@ -33,6 +33,15 @@ struct BorderRadiusData { } }; +using CornerRadius = Gfx::AntiAliasingPainter::CornerRadius; + +struct CornerRadii { + CornerRadius top_left; + CornerRadius top_right; + CornerRadius bottom_right; + CornerRadius bottom_left; +}; + struct BorderRadiiData { BorderRadiusData top_left; BorderRadiusData top_right; @@ -56,15 +65,16 @@ struct BorderRadiiData { { shrink(-top, -right, -bottom, -left); } -}; -using CornerRadius = Gfx::AntiAliasingPainter::CornerRadius; - -struct CornerRadii { - CornerRadius top_left; - CornerRadius top_right; - CornerRadius bottom_right; - CornerRadius bottom_left; + inline CornerRadii as_corners(PaintContext& context) const + { + return CornerRadii { + top_left.as_corner(context), + top_right.as_corner(context), + bottom_right.as_corner(context), + bottom_left.as_corner(context) + }; + } }; } diff --git a/Userland/Libraries/LibWeb/Painting/BordersData.cpp b/Userland/Libraries/LibWeb/Painting/BordersData.cpp new file mode 100644 index 0000000000..474c523450 --- /dev/null +++ b/Userland/Libraries/LibWeb/Painting/BordersData.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023, Aliaksandr Kalenik + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Web::Painting { + +BordersDataDevicePixels BordersData::to_device_pixels(PaintContext const& context) const +{ + return BordersDataDevicePixels { + BorderDataDevicePixels { + top.color, + top.line_style, + context.enclosing_device_pixels(top.width).value() }, + BorderDataDevicePixels { + right.color, + right.line_style, + context.enclosing_device_pixels(right.width).value() }, + BorderDataDevicePixels { + bottom.color, + bottom.line_style, + context.enclosing_device_pixels(bottom.width).value() }, + BorderDataDevicePixels { + left.color, + left.line_style, + context.enclosing_device_pixels(left.width).value() } + }; +} + +} diff --git a/Userland/Libraries/LibWeb/Painting/BordersData.h b/Userland/Libraries/LibWeb/Painting/BordersData.h index 84923cb4bb..a9784cfc37 100644 --- a/Userland/Libraries/LibWeb/Painting/BordersData.h +++ b/Userland/Libraries/LibWeb/Painting/BordersData.h @@ -7,13 +7,34 @@ #pragma once +#include +#include +#include +#include + namespace Web::Painting { +struct BorderDataDevicePixels { +public: + Color color { Color::Transparent }; + CSS::LineStyle line_style { CSS::LineStyle::None }; + DevicePixels width { 0 }; +}; + +struct BordersDataDevicePixels { + BorderDataDevicePixels top; + BorderDataDevicePixels right; + BorderDataDevicePixels bottom; + BorderDataDevicePixels left; +}; + struct BordersData { CSS::BorderData top; CSS::BorderData right; CSS::BorderData bottom; CSS::BorderData left; + + BordersDataDevicePixels to_device_pixels(PaintContext const& context) const; }; } diff --git a/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp b/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp index e7a65af2eb..102767c8e6 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, context.rounded_device_rect(borders_rect), border_radii_data, *outline_data); + paint_all_borders(context.painter(), context.rounded_device_rect(borders_rect), border_radii_data.as_corners(context), outline_data->to_device_pixels(context)); } else { - paint_all_borders(context, context.rounded_device_rect(borders_rect), border_radii_data, borders_data); + paint_all_borders(context.painter(), 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 462e8149bc..8b70a016ce 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, context.rounded_device_rect(borders_rect), border_radius_data, borders_data.value()); + paint_all_borders(context.painter(), 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, context.rounded_device_rect(absolute_border_box_rect()), normalized_border_radii_data(), borders_data); + 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)); } void PaintableBox::paint_backdrop_filter(PaintContext& context) const diff --git a/Userland/Libraries/LibWeb/Painting/TableBordersPainting.cpp b/Userland/Libraries/LibWeb/Painting/TableBordersPainting.cpp index 18a2c6e114..80850f362e 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, cell_rect, cell_box.normalized_border_radii_data(), borders_data); + paint_all_borders(context.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(), }; - paint_all_borders(context, context.rounded_device_rect(cell_box.absolute_border_box_rect()), cell_box.normalized_border_radii_data(), borders_data); + 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)); } } }