LibGfx+LibWeb: Move display-list corner types to LibGfx

Prep for moving display-list rasterization out of LibWeb by moving the
device-pixel corner radius, corner clip, and anti-aliasing types to
LibGfx.

Keep BorderRadiiData in LibWeb as the CSS-pixel representation and
convert it to Gfx corner radii when recording display-list commands.
This commit is contained in:
Aliaksandr Kalenik 2026-05-12 15:19:35 +02:00 committed by Alexander Kalenik
parent b9ed64d1ce
commit 537f289c0c
24 changed files with 211 additions and 171 deletions

View file

@ -6,7 +6,7 @@
#pragma once
namespace Web::Painting {
namespace Gfx {
enum class ShouldAntiAlias : bool {
Yes,

View file

@ -7,6 +7,7 @@ set(SOURCES
Color.cpp
ColorConversion.cpp
ColorSpace.cpp
CornerRadii.cpp
Cursor.cpp
Filter.cpp
Font/Font.cpp

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2020, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Math.h>
#include <LibGfx/CornerRadii.h>
namespace Gfx {
// https://drafts.csswg.org/css-backgrounds/#shadow-shape
static void add_spread_distance_to_border_radius(int& border_radius, int spread_distance)
{
if (border_radius == 0 || spread_distance == 0)
return;
// To preserve the box's shape when spread is applied, the corner radii of the shadow are also increased (decreased,
// for inner shadows) from the border-box (padding-box) radii by adding (subtracting) the spread distance (and flooring
// at zero). However, in order to create a sharper corner when the border radius is small (and thus ensure continuity
// between round and sharp corners), when the border radius is less than the spread distance (or in the case of an inner
// shadow, less than the absolute value of a negative spread distance), the spread distance is first multiplied by the
// proportion 1 + (r-1)^3, where r is the ratio of the border radius to the spread distance, in calculating the corner
// radii of the spread shadow shape.
if (border_radius > AK::abs(spread_distance)) {
border_radius += spread_distance;
} else {
auto r = static_cast<float>(border_radius) / AK::abs(spread_distance);
border_radius += spread_distance * (1 + AK::pow(r - 1, 3.0f));
}
}
void CornerRadii::adjust_corners_for_spread_distance(int spread_distance)
{
add_spread_distance_to_border_radius(top_left.horizontal_radius, spread_distance);
add_spread_distance_to_border_radius(top_left.vertical_radius, spread_distance);
add_spread_distance_to_border_radius(top_right.horizontal_radius, spread_distance);
add_spread_distance_to_border_radius(top_right.vertical_radius, spread_distance);
add_spread_distance_to_border_radius(bottom_right.horizontal_radius, spread_distance);
add_spread_distance_to_border_radius(bottom_right.vertical_radius, spread_distance);
add_spread_distance_to_border_radius(bottom_left.horizontal_radius, spread_distance);
add_spread_distance_to_border_radius(bottom_left.vertical_radius, spread_distance);
}
}

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2020, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibGfx/Point.h>
#include <LibGfx/Rect.h>
namespace Gfx {
enum class CornerClip {
Outside,
Inside
};
struct CornerRadius {
int horizontal_radius { 0 };
int vertical_radius { 0 };
inline operator bool() const
{
return horizontal_radius > 0 && vertical_radius > 0;
}
};
struct CornerRadii {
CornerRadius top_left;
CornerRadius top_right;
CornerRadius bottom_right;
CornerRadius bottom_left;
inline bool has_any_radius() const
{
return top_left || top_right || bottom_right || bottom_left;
}
void adjust_corners_for_spread_distance(int spread_distance);
bool contains(IntPoint point, IntRect const& rect) const
{
if (!rect.contains(point))
return false;
if (!has_any_radius())
return true;
auto const px = point.x();
auto const py = point.y();
auto outside_ellipse = [&](CornerRadius const& r, int cx, int cy) {
auto dx = static_cast<float>(px - cx) / r.horizontal_radius;
auto dy = static_cast<float>(py - cy) / r.vertical_radius;
return dx * dx + dy * dy > 1.f;
};
if (top_left) {
auto cx = rect.left() + top_left.horizontal_radius;
auto cy = rect.top() + top_left.vertical_radius;
if (px < cx && py < cy && outside_ellipse(top_left, cx, cy))
return false;
}
if (top_right) {
auto cx = rect.right() - top_right.horizontal_radius;
auto cy = rect.top() + top_right.vertical_radius;
if (px > cx && py < cy && outside_ellipse(top_right, cx, cy))
return false;
}
if (bottom_right) {
auto cx = rect.right() - bottom_right.horizontal_radius;
auto cy = rect.bottom() - bottom_right.vertical_radius;
if (px > cx && py > cy && outside_ellipse(bottom_right, cx, cy))
return false;
}
if (bottom_left) {
auto cx = rect.left() + bottom_left.horizontal_radius;
auto cy = rect.bottom() - bottom_left.vertical_radius;
if (px < cx && py > cy && outside_ellipse(bottom_left, cx, cy))
return false;
}
return true;
}
};
}

View file

@ -1026,8 +1026,6 @@ class VideoPaintable;
class ViewportPaintable;
enum class PaintPhase;
enum class ShouldAntiAlias : bool;
struct BorderRadiiData;
struct BorderRadiusData;
struct LinearGradientData;

View file

@ -11,13 +11,13 @@
#include <AK/Variant.h>
#include <AK/Vector.h>
#include <LibGfx/CompositingAndBlendingOperator.h>
#include <LibGfx/CornerRadii.h>
#include <LibGfx/Filter.h>
#include <LibGfx/Matrix4x4.h>
#include <LibGfx/Path.h>
#include <LibGfx/Point.h>
#include <LibGfx/Rect.h>
#include <LibGfx/WindingRule.h>
#include <LibWeb/Painting/BorderRadiiData.h>
#include <LibWeb/Painting/ScrollFrame.h>
#include <LibWeb/PixelUnits.h>
@ -34,9 +34,9 @@ struct ScrollData {
struct ClipData {
DevicePixelRect rect;
CornerRadii corner_radii;
Gfx::CornerRadii corner_radii;
ClipData(DevicePixelRect r, CornerRadii radii)
ClipData(DevicePixelRect r, Gfx::CornerRadii radii)
: rect(r)
, corner_radii(radii)
{

View file

@ -16,6 +16,7 @@
#include <LibWeb/Layout/Viewport.h>
#include <LibWeb/Painting/BackgroundPainting.h>
#include <LibWeb/Painting/Blending.h>
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
#include <LibWeb/Painting/DisplayListRecorder.h>
#include <LibWeb/Painting/PaintableWithLines.h>
@ -145,7 +146,7 @@ void paint_background(DisplayListRecordingContext& context, PaintableBox const&
CSSPixelRect const& css_clip_rect = clip_box.rect;
auto clip_rect = context.rounded_device_rect(css_clip_rect);
ScopedCornerRadiusClip corner_clip { context, context.rounded_device_rect(css_clip_rect), clip_box.radii, CornerClip::Outside, !is_root_element };
ScopedCornerRadiusClip corner_clip { context, context.rounded_device_rect(css_clip_rect), clip_box.radii, Gfx::CornerClip::Outside, !is_root_element };
if (!is_root_element) {
display_list_recorder.add_clip_rect(clip_rect.to_type<int>());

View file

@ -9,6 +9,7 @@
#include <LibWeb/Export.h>
#include <LibWeb/Forward.h>
#include <LibWeb/Painting/BorderPainting.h>
#include <LibWeb/Painting/BorderRadiiData.h>
namespace Web::Painting {

View file

@ -10,6 +10,7 @@
#include <LibWeb/CSS/StyleValues/KeywordStyleValue.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/Layout/Node.h>
#include <LibWeb/Painting/BorderPainting.h>
#include <LibWeb/Painting/DisplayListRecorder.h>
namespace Web::Painting {
@ -54,7 +55,7 @@ Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_
return border_data.color;
}
void paint_border(DisplayListRecorder& painter, BorderEdge edge, DevicePixelRect const& rect, CornerRadius const& radius, CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::Path& path, bool last)
void paint_border(DisplayListRecorder& painter, BorderEdge edge, DevicePixelRect const& rect, Gfx::CornerRadius const& radius, Gfx::CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::Path& path, bool last)
{
auto const& border_data = borders_data.for_edge(edge);
@ -98,8 +99,8 @@ void paint_border(DisplayListRecorder& painter, BorderEdge edge, DevicePixelRect
paint_border(painter, edge, modified_rect, radius, opposite_radius, modified_borders_data, path, true);
// Inner border, with smaller rect and radii
CornerRadius modified_radius = radius;
CornerRadius modified_opposite_radius = opposite_radius;
Gfx::CornerRadius modified_radius = radius;
Gfx::CornerRadius modified_opposite_radius = opposite_radius;
switch (edge) {
case BorderEdge::Top: {
auto top_inset = borders_data.top.width - modified_borders_data.top.width;
@ -585,7 +586,7 @@ void paint_border(DisplayListRecorder& painter, BorderEdge edge, DevicePixelRect
}
}
void paint_all_borders(DisplayListRecorder& painter, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data)
void paint_all_borders(DisplayListRecorder& painter, DevicePixelRect const& border_rect, Gfx::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

@ -7,11 +7,11 @@
#pragma once
#include <LibGfx/CornerRadii.h>
#include <LibGfx/Forward.h>
#include <LibWeb/CSS/ComputedValues.h>
#include <LibWeb/Export.h>
#include <LibWeb/Forward.h>
#include <LibWeb/Painting/BorderRadiiData.h>
#include <LibWeb/Painting/BordersData.h>
namespace Web::Painting {
@ -19,8 +19,8 @@ namespace Web::Painting {
// Returns OptionalNone if there is no outline to paint.
WEB_API Optional<BordersData> borders_data_for_outline(Layout::Node const&, Color outline_color, CSS::OutlineStyle outline_style, CSSPixels outline_width);
void paint_border(DisplayListRecorder& painter, BorderEdge edge, DevicePixelRect const& rect, CornerRadius const& radius, CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::Path&, bool last);
WEB_API void paint_all_borders(DisplayListRecorder& painter, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const&);
void paint_border(DisplayListRecorder& painter, BorderEdge edge, DevicePixelRect const& rect, Gfx::CornerRadius const& radius, Gfx::CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::Path&, bool last);
WEB_API void paint_all_borders(DisplayListRecorder& painter, DevicePixelRect const& border_rect, Gfx::CornerRadii const& corner_radii, BordersDataDevicePixels const&);
Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_data);

View file

@ -10,45 +10,12 @@
namespace Web::Painting {
CornerRadius BorderRadiusData::as_corner(DevicePixelConverter const& device_pixel_scale) const
Gfx::CornerRadius BorderRadiusData::as_corner(DevicePixelConverter const& device_pixel_scale) const
{
return CornerRadius {
return Gfx::CornerRadius {
device_pixel_scale.floored_device_pixels(horizontal_radius).value(),
device_pixel_scale.floored_device_pixels(vertical_radius).value()
};
}
// https://drafts.csswg.org/css-backgrounds/#shadow-shape
static void add_spread_distance_to_border_radius(int& border_radius, int spread_distance)
{
if (border_radius == 0 || spread_distance == 0)
return;
// To preserve the box's shape when spread is applied, the corner radii of the shadow are also increased (decreased,
// for inner shadows) from the border-box (padding-box) radii by adding (subtracting) the spread distance (and flooring
// at zero). However, in order to create a sharper corner when the border radius is small (and thus ensure continuity
// between round and sharp corners), when the border radius is less than the spread distance (or in the case of an inner
// shadow, less than the absolute value of a negative spread distance), the spread distance is first multiplied by the
// proportion 1 + (r-1)^3, where r is the ratio of the border radius to the spread distance, in calculating the corner
// radii of the spread shadow shape.
if (border_radius > AK::abs(spread_distance)) {
border_radius += spread_distance;
} else {
auto r = (float)border_radius / AK::abs(spread_distance);
border_radius += spread_distance * (1 + AK::pow(r - 1, 3.0f));
}
}
void CornerRadii::adjust_corners_for_spread_distance(int spread_distance)
{
add_spread_distance_to_border_radius(top_left.horizontal_radius, spread_distance);
add_spread_distance_to_border_radius(top_left.vertical_radius, spread_distance);
add_spread_distance_to_border_radius(top_right.horizontal_radius, spread_distance);
add_spread_distance_to_border_radius(top_right.vertical_radius, spread_distance);
add_spread_distance_to_border_radius(bottom_right.horizontal_radius, spread_distance);
add_spread_distance_to_border_radius(bottom_right.vertical_radius, spread_distance);
add_spread_distance_to_border_radius(bottom_left.horizontal_radius, spread_distance);
add_spread_distance_to_border_radius(bottom_left.vertical_radius, spread_distance);
}
}

View file

@ -7,28 +7,17 @@
#pragma once
#include <LibGfx/Point.h>
#include <LibGfx/Rect.h>
#include <LibGfx/CornerRadii.h>
#include <LibWeb/CSS/ComputedValues.h>
#include <LibWeb/Export.h>
namespace Web::Painting {
struct CornerRadius {
int horizontal_radius { 0 };
int vertical_radius { 0 };
inline operator bool() const
{
return horizontal_radius > 0 && vertical_radius > 0;
}
};
struct WEB_API BorderRadiusData {
CSSPixels horizontal_radius { 0 };
CSSPixels vertical_radius { 0 };
CornerRadius as_corner(DevicePixelConverter const& device_pixel_converter) const;
Gfx::CornerRadius as_corner(DevicePixelConverter const& device_pixel_converter) const;
inline operator bool() const
{
@ -44,68 +33,6 @@ struct WEB_API BorderRadiusData {
}
};
struct CornerRadii {
CornerRadius top_left;
CornerRadius top_right;
CornerRadius bottom_right;
CornerRadius bottom_left;
inline bool has_any_radius() const
{
return top_left || top_right || bottom_right || bottom_left;
}
void adjust_corners_for_spread_distance(int spread_distance);
bool contains(Gfx::IntPoint point, Gfx::IntRect const& rect) const
{
if (!rect.contains(point))
return false;
if (!has_any_radius())
return true;
auto const px = point.x();
auto const py = point.y();
auto outside_ellipse = [&](CornerRadius const& r, int cx, int cy) {
auto dx = static_cast<float>(px - cx) / r.horizontal_radius;
auto dy = static_cast<float>(py - cy) / r.vertical_radius;
return dx * dx + dy * dy > 1.f;
};
if (top_left) {
auto cx = rect.left() + top_left.horizontal_radius;
auto cy = rect.top() + top_left.vertical_radius;
if (px < cx && py < cy && outside_ellipse(top_left, cx, cy))
return false;
}
if (top_right) {
auto cx = rect.right() - top_right.horizontal_radius;
auto cy = rect.top() + top_right.vertical_radius;
if (px > cx && py < cy && outside_ellipse(top_right, cx, cy))
return false;
}
if (bottom_right) {
auto cx = rect.right() - bottom_right.horizontal_radius;
auto cy = rect.bottom() - bottom_right.vertical_radius;
if (px > cx && py > cy && outside_ellipse(bottom_right, cx, cy))
return false;
}
if (bottom_left) {
auto cx = rect.left() + bottom_left.horizontal_radius;
auto cy = rect.bottom() - bottom_left.vertical_radius;
if (px < cx && py > cy && outside_ellipse(bottom_left, cx, cy))
return false;
}
return true;
}
};
struct BorderRadiiData {
BorderRadiusData top_left;
BorderRadiusData top_right;
@ -125,10 +52,10 @@ struct BorderRadiiData {
if (!has_any_radius())
return true;
auto to_corner = [](BorderRadiusData const& r) -> CornerRadius {
auto to_corner = [](BorderRadiusData const& r) -> Gfx::CornerRadius {
return { static_cast<int>(r.horizontal_radius.to_float()), static_cast<int>(r.vertical_radius.to_float()) };
};
CornerRadii corners { to_corner(top_left), to_corner(top_right), to_corner(bottom_right), to_corner(bottom_left) };
Gfx::CornerRadii corners { to_corner(top_left), to_corner(top_right), to_corner(bottom_right), to_corner(bottom_left) };
return corners.contains(point.to_type<int>(), rect.to_type<int>());
}
@ -145,11 +72,11 @@ struct BorderRadiiData {
shrink(-top, -right, -bottom, -left);
}
inline CornerRadii as_corners(DevicePixelConverter const& device_pixel_converter) const
inline Gfx::CornerRadii as_corners(DevicePixelConverter const& device_pixel_converter) const
{
if (!has_any_radius())
return {};
return CornerRadii {
return Gfx::CornerRadii {
top_left.as_corner(device_pixel_converter),
top_right.as_corner(device_pixel_converter),
bottom_right.as_corner(device_pixel_converter),

View file

@ -4,19 +4,20 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Painting/BorderRadiiData.h>
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
#include <LibWeb/Painting/DisplayListRecorder.h>
#include <LibWeb/Painting/DisplayListRecordingContext.h>
namespace Web::Painting {
ScopedCornerRadiusClip::ScopedCornerRadiusClip(DisplayListRecordingContext& context, DevicePixelRect const& border_rect, BorderRadiiData const& border_radii, CornerClip corner_clip, bool do_apply)
ScopedCornerRadiusClip::ScopedCornerRadiusClip(DisplayListRecordingContext& context, DevicePixelRect const& border_rect, BorderRadiiData const& border_radii, Gfx::CornerClip corner_clip, bool do_apply)
: m_context(context)
{
m_do_apply = do_apply;
if (!do_apply)
return;
CornerRadii const corner_radii {
Gfx::CornerRadii const corner_radii {
.top_left = border_radii.top_left.as_corner(context.device_pixel_converter()),
.top_right = border_radii.top_right.as_corner(context.device_pixel_converter()),
.bottom_right = border_radii.bottom_right.as_corner(context.device_pixel_converter()),

View file

@ -6,18 +6,22 @@
#pragma once
#include <LibGfx/CornerRadii.h>
#include <LibWeb/Export.h>
#include <LibWeb/Painting/BorderPainting.h>
#include <LibWeb/PixelUnits.h>
namespace Web {
class DisplayListRecordingContext;
}
namespace Web::Painting {
enum class CornerClip {
Outside,
Inside
};
struct BorderRadiiData;
struct WEB_API ScopedCornerRadiusClip {
ScopedCornerRadiusClip(DisplayListRecordingContext& context, DevicePixelRect const& border_rect, BorderRadiiData const& border_radii, CornerClip corner_clip = CornerClip::Outside, bool do_apply = true);
ScopedCornerRadiusClip(DisplayListRecordingContext& context, DevicePixelRect const& border_rect, BorderRadiiData const& border_radii, Gfx::CornerClip corner_clip = Gfx::CornerClip::Outside, bool do_apply = true);
~ScopedCornerRadiusClip();

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
#include <LibWeb/Painting/CanvasPaintable.h>
#include <LibWeb/Painting/DisplayListRecorder.h>

View file

@ -189,7 +189,7 @@ void DisplayListPlayer::execute_impl(
add_rounded_rect_clip({
.corner_radii = clip.corner_radii,
.border_rect = clip.rect.to_type<int>(),
.corner_clip = CornerClip::Outside,
.corner_clip = Gfx::CornerClip::Outside,
});
} else {
add_clip_rect({ .rect = clip.rect.to_type<int>() });

View file

@ -12,8 +12,10 @@
#include <AK/StdLibExtras.h>
#include <AK/Types.h>
#include <LibGfx/AffineTransform.h>
#include <LibGfx/AntiAliasing.h>
#include <LibGfx/Color.h>
#include <LibGfx/CompositingAndBlendingOperator.h>
#include <LibGfx/CornerRadii.h>
#include <LibGfx/GradientInterpolation.h>
#include <LibGfx/InterpolationColorSpace.h>
#include <LibGfx/LineStyle.h>
@ -23,11 +25,8 @@
#include <LibGfx/ScalingMode.h>
#include <LibGfx/Size.h>
#include <LibWeb/Painting/AccumulatedVisualContext.h>
#include <LibWeb/Painting/BorderRadiiData.h>
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
#include <LibWeb/Painting/DisplayListResourceIds.h>
#include <LibWeb/Painting/ScrollState.h>
#include <LibWeb/Painting/ShouldAntiAlias.h>
namespace Web::Painting {
@ -244,9 +243,9 @@ struct PaintOuterBoxShadow {
Gfx::Color color;
int blur_radius;
Gfx::IntRect device_content_rect;
CornerRadii content_corner_radii;
Gfx::CornerRadii content_corner_radii;
Gfx::IntRect shadow_rect;
CornerRadii shadow_corner_radii;
Gfx::CornerRadii shadow_corner_radii;
[[nodiscard]] Gfx::IntRect bounding_rect() const;
void dump(StringBuilder&) const;
@ -259,10 +258,10 @@ struct PaintInnerBoxShadow {
Gfx::Color color;
int blur_radius;
Gfx::IntRect device_content_rect;
CornerRadii content_corner_radii;
Gfx::CornerRadii content_corner_radii;
Gfx::IntRect outer_shadow_rect;
Gfx::IntRect inner_shadow_rect;
CornerRadii inner_shadow_corner_radii;
Gfx::CornerRadii inner_shadow_corner_radii;
[[nodiscard]] Gfx::IntRect bounding_rect() const;
void dump(StringBuilder&) const;
@ -291,7 +290,7 @@ struct FillRectWithRoundedCorners {
Gfx::IntRect rect;
Color color;
CornerRadii corner_radii;
Gfx::CornerRadii corner_radii;
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
void dump(StringBuilder&) const;
@ -347,7 +346,7 @@ struct FillPath {
Color color;
DisplayListPaintStyle paint_style;
Gfx::WindingRule winding_rule;
ShouldAntiAlias should_anti_alias { ShouldAntiAlias::Yes };
Gfx::ShouldAntiAlias should_anti_alias { Gfx::ShouldAntiAlias::Yes };
[[nodiscard]] Gfx::IntRect bounding_rect() const { return path_bounding_rect; }
@ -370,7 +369,7 @@ struct StrokePath {
Color color;
DisplayListPaintStyle paint_style;
float thickness;
ShouldAntiAlias should_anti_alias { ShouldAntiAlias::Yes };
Gfx::ShouldAntiAlias should_anti_alias { Gfx::ShouldAntiAlias::Yes };
[[nodiscard]] Gfx::IntRect bounding_rect() const { return path_bounding_rect; }
@ -422,7 +421,7 @@ struct ApplyBackdropFilter {
static constexpr DisplayListCommandType command_type = DisplayListCommandType::ApplyBackdropFilter;
Gfx::IntRect backdrop_region;
CornerRadii corner_radii;
Gfx::CornerRadii corner_radii;
bool has_backdrop_filter { false };
DisplayListDataSpan backdrop_filter_data;
@ -478,9 +477,9 @@ struct AddRoundedRectClip {
static constexpr StringView command_name = "AddRoundedRectClip"sv;
static constexpr DisplayListCommandType command_type = DisplayListCommandType::AddRoundedRectClip;
CornerRadii corner_radii;
Gfx::CornerRadii corner_radii;
Gfx::IntRect border_rect;
CornerClip corner_clip;
Gfx::CornerClip corner_clip;
[[nodiscard]] Gfx::IntRect bounding_rect() const { return border_rect; }
bool is_clip() const { return true; }

View file

@ -58,7 +58,7 @@ DisplayListPlayerSkia::~DisplayListPlayerSkia()
{
}
static SkRRect to_skia_rrect(auto const& rect, CornerRadii const& corner_radii)
static SkRRect to_skia_rrect(auto const& rect, Gfx::CornerRadii const& corner_radii)
{
SkRRect rrect;
SkVector radii[4];
@ -622,7 +622,7 @@ void DisplayListPlayerSkia::fill_path(FillPath const& command)
} else {
paint.setColor(to_skia_color(command.color));
}
paint.setAntiAlias(command.should_anti_alias == ShouldAntiAlias::Yes);
paint.setAntiAlias(command.should_anti_alias == Gfx::ShouldAntiAlias::Yes);
surface().canvas().drawPath(path, paint);
}
@ -636,7 +636,7 @@ void DisplayListPlayerSkia::stroke_path(StrokePath const& command)
} else {
paint.setColor(to_skia_color(command.color));
}
paint.setAntiAlias(command.should_anti_alias == ShouldAntiAlias::Yes);
paint.setAntiAlias(command.should_anti_alias == Gfx::ShouldAntiAlias::Yes);
paint.setStyle(SkPaint::Style::kStroke_Style);
paint.setStrokeWidth(command.thickness);
paint.setStrokeCap(to_skia_cap(command.cap_style));
@ -807,7 +807,7 @@ void DisplayListPlayerSkia::add_rounded_rect_clip(AddRoundedRectClip const& comm
{
auto rounded_rect = to_skia_rrect(command.border_rect, command.corner_radii);
auto& canvas = surface().canvas();
auto clip_op = command.corner_clip == CornerClip::Inside ? SkClipOp::kDifference : SkClipOp::kIntersect;
auto clip_op = command.corner_clip == Gfx::CornerClip::Inside ? SkClipOp::kDifference : SkClipOp::kIntersect;
canvas.clipRRect(rounded_rect, clip_op, true);
}

View file

@ -295,7 +295,7 @@ void DisplayListRecorder::paint_nested_display_list(RefPtr<DisplayList> display_
payload_builder.inline_data());
}
void DisplayListRecorder::add_rounded_rect_clip(CornerRadii corner_radii, Gfx::IntRect border_rect, CornerClip corner_clip)
void DisplayListRecorder::add_rounded_rect_clip(Gfx::CornerRadii corner_radii, Gfx::IntRect border_rect, Gfx::CornerClip corner_clip)
{
append_command(AddRoundedRectClip { corner_radii, border_rect, corner_clip });
}
@ -624,7 +624,7 @@ void DisplayListRecorder::restore()
append_command(Restore {});
}
void DisplayListRecorder::apply_backdrop_filter(Gfx::IntRect const& backdrop_region, CornerRadii const& corner_radii, Gfx::Filter const& backdrop_filter)
void DisplayListRecorder::apply_backdrop_filter(Gfx::IntRect const& backdrop_region, Gfx::CornerRadii const& corner_radii, Gfx::Filter const& backdrop_filter)
{
if (backdrop_region.is_empty())
return;
@ -669,7 +669,7 @@ void DisplayListRecorder::paint_text_shadow(int blur_radius, Gfx::IntRect boundi
payload_builder.inline_data());
}
void DisplayListRecorder::fill_rect_with_rounded_corners(Gfx::IntRect const& rect, Color color, CornerRadii const& corner_radii)
void DisplayListRecorder::fill_rect_with_rounded_corners(Gfx::IntRect const& rect, Color color, Gfx::CornerRadii const& corner_radii)
{
if (rect.is_empty() || color.alpha() == 0)
return;

View file

@ -8,8 +8,10 @@
#include <AK/Forward.h>
#include <AK/Vector.h>
#include <LibGfx/AntiAliasing.h>
#include <LibGfx/Color.h>
#include <LibGfx/CompositingAndBlendingOperator.h>
#include <LibGfx/CornerRadii.h>
#include <LibGfx/Forward.h>
#include <LibGfx/LineStyle.h>
#include <LibGfx/PaintStyle.h>
@ -21,13 +23,10 @@
#include <LibWeb/Export.h>
#include <LibWeb/Forward.h>
#include <LibWeb/Painting/AccumulatedVisualContext.h>
#include <LibWeb/Painting/BorderRadiiData.h>
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
#include <LibWeb/Painting/DisplayList.h>
#include <LibWeb/Painting/DisplayListCommand.h>
#include <LibWeb/Painting/GradientData.h>
#include <LibWeb/Painting/PaintStyle.h>
#include <LibWeb/Painting/ShouldAntiAlias.h>
namespace Web::Painting {
@ -44,7 +43,7 @@ public:
float opacity = 1.0f;
PaintStyleOrColor paint_style_or_color;
Gfx::WindingRule winding_rule = Gfx::WindingRule::EvenOdd;
ShouldAntiAlias should_anti_alias { ShouldAntiAlias::Yes };
Gfx::ShouldAntiAlias should_anti_alias { Gfx::ShouldAntiAlias::Yes };
};
void fill_path(FillPathParams params);
@ -58,7 +57,7 @@ public:
float opacity = 1.0f;
PaintStyleOrColor paint_style_or_color;
float thickness;
ShouldAntiAlias should_anti_alias { ShouldAntiAlias::Yes };
Gfx::ShouldAntiAlias should_anti_alias { Gfx::ShouldAntiAlias::Yes };
};
void stroke_path(StrokePathParams);
@ -119,7 +118,7 @@ public:
void paint_nested_display_list(RefPtr<DisplayList> display_list, Gfx::IntRect rect);
void add_rounded_rect_clip(CornerRadii corner_radii, Gfx::IntRect border_rect, CornerClip corner_clip);
void add_rounded_rect_clip(Gfx::CornerRadii corner_radii, Gfx::IntRect border_rect, Gfx::CornerClip corner_clip);
struct MaskInfo {
RefPtr<DisplayList> display_list;
@ -129,13 +128,13 @@ public:
void begin_masks(ReadonlySpan<MaskInfo>);
void end_masks(ReadonlySpan<MaskInfo>);
void apply_backdrop_filter(Gfx::IntRect const& backdrop_region, CornerRadii const& corner_radii, Gfx::Filter const& backdrop_filter);
void apply_backdrop_filter(Gfx::IntRect const& backdrop_region, Gfx::CornerRadii const& corner_radii, Gfx::Filter const& backdrop_filter);
void paint_outer_box_shadow(PaintOuterBoxShadow);
void paint_inner_box_shadow(PaintInnerBoxShadow);
void paint_text_shadow(int blur_radius, Gfx::IntRect bounding_rect, Gfx::IntRect text_rect, Gfx::GlyphRun const&, double glyph_run_scale, Color color, Gfx::FloatPoint draw_location);
void fill_rect_with_rounded_corners(Gfx::IntRect const& rect, Color color, CornerRadii const&);
void fill_rect_with_rounded_corners(Gfx::IntRect const& rect, Color color, Gfx::CornerRadii const&);
void fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int radius);
void fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int top_left_radius, int top_right_radius, int bottom_right_radius, int bottom_left_radius);

View file

@ -19,6 +19,7 @@
#include <LibWeb/Page/MiddleButtonScrollHandler.h>
#include <LibWeb/Page/Page.h>
#include <LibWeb/Painting/BackgroundPainting.h>
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
#include <LibWeb/Painting/ChromeMetrics.h>
#include <LibWeb/Painting/DisplayListRecorder.h>
#include <LibWeb/Painting/PaintableBox.h>

View file

@ -71,12 +71,12 @@ CSSPixelRect SVGPaintable::compute_absolute_rect() const
return PaintableBox::compute_absolute_rect();
}
ShouldAntiAlias SVGPaintable::should_anti_alias() const
Gfx::ShouldAntiAlias SVGPaintable::should_anti_alias() const
{
auto shape_rendering = computed_values().shape_rendering();
if (first_is_one_of(shape_rendering, CSS::ShapeRendering::Optimizespeed, CSS::ShapeRendering::Crispedges))
return ShouldAntiAlias::No;
return ShouldAntiAlias::Yes;
return Gfx::ShouldAntiAlias::No;
return Gfx::ShouldAntiAlias::Yes;
}
}

View file

@ -6,6 +6,7 @@
#pragma once
#include <LibGfx/AntiAliasing.h>
#include <LibWeb/Layout/SVGBox.h>
#include <LibWeb/Painting/PaintableBox.h>
@ -26,7 +27,7 @@ protected:
virtual CSSPixelRect compute_absolute_rect() const override;
ShouldAntiAlias should_anti_alias() const;
Gfx::ShouldAntiAlias should_anti_alias() const;
};
template<>

View file

@ -53,7 +53,7 @@ void paint_box_shadow(DisplayListRecordingContext& context,
auto shrinked_border_radii = border_radii;
shrinked_border_radii.shrink(borders_data.top.width, borders_data.right.width, borders_data.bottom.width, borders_data.left.width);
ScopedCornerRadiusClip corner_clipper { context, device_content_rect, shrinked_border_radii, CornerClip::Outside };
ScopedCornerRadiusClip corner_clipper { context, device_content_rect, shrinked_border_radii, Gfx::CornerClip::Outside };
context.display_list_recorder().paint_inner_box_shadow(PaintInnerBoxShadow {
.color = box_shadow_data.color,
.blur_radius = blur_radius,
@ -71,7 +71,7 @@ void paint_box_shadow(DisplayListRecordingContext& context,
auto shadow_corner_radii = corner_radii;
shadow_corner_radii.adjust_corners_for_spread_distance(spread_distance);
ScopedCornerRadiusClip corner_clipper { context, device_content_rect, border_radii, CornerClip::Inside };
ScopedCornerRadiusClip corner_clipper { context, device_content_rect, border_radii, Gfx::CornerClip::Inside };
context.display_list_recorder().paint_outer_box_shadow(PaintOuterBoxShadow {
.color = box_shadow_data.color,
.blur_radius = blur_radius,