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:
parent
b9ed64d1ce
commit
537f289c0c
24 changed files with 211 additions and 171 deletions
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
namespace Web::Painting {
|
||||
namespace Gfx {
|
||||
|
||||
enum class ShouldAntiAlias : bool {
|
||||
Yes,
|
||||
|
|
@ -7,6 +7,7 @@ set(SOURCES
|
|||
Color.cpp
|
||||
ColorConversion.cpp
|
||||
ColorSpace.cpp
|
||||
CornerRadii.cpp
|
||||
Cursor.cpp
|
||||
Filter.cpp
|
||||
Font/Font.cpp
|
||||
|
|
|
|||
46
Libraries/LibGfx/CornerRadii.cpp
Normal file
46
Libraries/LibGfx/CornerRadii.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
92
Libraries/LibGfx/CornerRadii.h
Normal file
92
Libraries/LibGfx/CornerRadii.h
Normal 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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1026,8 +1026,6 @@ class VideoPaintable;
|
|||
class ViewportPaintable;
|
||||
|
||||
enum class PaintPhase;
|
||||
enum class ShouldAntiAlias : bool;
|
||||
|
||||
struct BorderRadiiData;
|
||||
struct BorderRadiusData;
|
||||
struct LinearGradientData;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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>());
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>() });
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<>
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue