LibWeb: Port painting to use the new Skia-backed Gfx::Path

SVG and and CSS border rendering now sits on top of SkPath instead of
the old Gfx::DeprecatedPath.

Due to an imperceptible (255, 255, 255) vs (255, 254, 255) color diff
in one ref test, I changed that test to not depend on border rendering
for a positive result, since that was incidental.
This commit is contained in:
Andreas Kling 2024-08-09 14:00:10 +02:00 committed by Andreas Kling
parent a3cc03f180
commit 137038b185
Notes: github-actions[bot] 2024-08-20 07:38:12 +00:00
37 changed files with 139 additions and 143 deletions

View file

@ -7,8 +7,8 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
" "
frag 2 from BlockContainer start: 0, length: 0, rect: [319,51 0x108] baseline: 110
SVGSVGBox <svg> at (9,9) content-size 300x150 [SVG] children: not-inline
SVGGraphicsBox <a> at (29,25.015625) content-size 193.59375x67.578125 children: not-inline
SVGTextBox <text> at (29,25.015625) content-size 193.59375x67.578125 children: inline
SVGGraphicsBox <a> at (33.765625,32.4375) content-size 188.71875x60.15625 children: not-inline
SVGTextBox <text> at (33.765625,32.4375) content-size 188.71875x60.15625 children: inline
TextNode <#text>
TextNode <#text>
BlockContainer <math> at (319,51) content-size 0x108 children: not-inline
@ -28,8 +28,8 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x201]
PaintableWithLines (BlockContainer(anonymous)) [8,8 784x155]
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 302x152]
SVGGraphicsPaintable (SVGGraphicsBox<a>) [29,25.015625 193.59375x67.578125]
SVGPathPaintable (SVGTextBox<text>) [29,25.015625 193.59375x67.578125]
SVGGraphicsPaintable (SVGGraphicsBox<a>) [33.765625,32.4375 188.71875x60.15625]
SVGPathPaintable (SVGTextBox<text>) [33.765625,32.4375 188.71875x60.15625]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<math>) [318,50 2x110] overflow: [319,51 100x100]
PaintableWithLines (BlockContainer<a>) [319,51 100x100]

View file

@ -5,16 +5,16 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
SVGSVGBox <svg> at (8,8) content-size 784x261.328125 [SVG] children: inline
TextNode <#text>
TextNode <#text>
SVGTextBox <text.small> at (86.40625,65.5) content-size 48.109375x37.484375 children: inline
SVGTextBox <text.small> at (89.46875,67.40625) content-size 46.46875x35.578125 children: inline
TextNode <#text>
TextNode <#text>
SVGTextBox <text.heavy> at (141.28125,21.078125) content-size 148.234375x79.71875 children: inline
SVGTextBox <text.heavy> at (146.25,35.34375) content-size 145.90625x65.453125 children: inline
TextNode <#text>
TextNode <#text>
SVGTextBox <text.small> at (204,117.765625) content-size 34.578125x34.703125 children: inline
SVGTextBox <text.small> at (206.6875,119.796875) content-size 32.84375x32.671875 children: inline
TextNode <#text>
TextNode <#text>
SVGTextBox <text.Rrrrr> at (243.1875,47.21875) content-size 519.484375x115.359375 children: inline
SVGTextBox <text.Rrrrr> at (249.828125,56.546875) content-size 514.125x106.03125 children: inline
TextNode <#text>
TextNode <#text>
TextNode <#text>
@ -23,7 +23,7 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x261.328125]
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 784x261.328125]
SVGPathPaintable (SVGTextBox<text>.small) [86.40625,65.5 48.109375x37.484375]
SVGPathPaintable (SVGTextBox<text>.heavy) [141.28125,21.078125 148.234375x79.71875]
SVGPathPaintable (SVGTextBox<text>.small) [204,117.765625 34.578125x34.703125]
SVGPathPaintable (SVGTextBox<text>.Rrrrr) [243.1875,47.21875 519.484375x115.359375]
SVGPathPaintable (SVGTextBox<text>.small) [89.46875,67.40625 46.46875x35.578125]
SVGPathPaintable (SVGTextBox<text>.heavy) [146.25,35.34375 145.90625x65.453125]
SVGPathPaintable (SVGTextBox<text>.small) [206.6875,119.796875 32.84375x32.671875]
SVGPathPaintable (SVGTextBox<text>.Rrrrr) [249.828125,56.546875 514.125x106.03125]

View file

@ -5,16 +5,16 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
SVGSVGBox <svg> at (8,8) content-size 784x261.328125 [SVG] children: inline
TextNode <#text>
TextNode <#text>
SVGTextBox <text.small> at (73.328125,88.359375) content-size 48.109375x37.484375 children: inline
SVGTextBox <text.small> at (76.40625,90.28125) content-size 46.46875x35.578125 children: inline
TextNode <#text>
TextNode <#text>
SVGTextBox <text.heavy> at (138.65625,43.953125) content-size 148.234375x79.71875 children: inline
SVGTextBox <text.heavy> at (143.640625,58.21875) content-size 145.90625x65.453125 children: inline
TextNode <#text>
TextNode <#text>
SVGTextBox <text.small> at (187.65625,153.703125) content-size 34.578125x34.703125 children: inline
SVGTextBox <text.small> at (190.359375,155.734375) content-size 32.84375x32.671875 children: inline
TextNode <#text>
TextNode <#text>
SVGTextBox <text.Rrrrr> at (220.328125,83.15625) content-size 519.484375x115.359375 children: inline
SVGTextBox <text.Rrrrr> at (226.96875,92.46875) content-size 514.125x106.03125 children: inline
TextNode <#text>
TextNode <#text>
TextNode <#text>
@ -23,7 +23,7 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x261.328125]
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 784x261.328125]
SVGPathPaintable (SVGTextBox<text>.small) [73.328125,88.359375 48.109375x37.484375]
SVGPathPaintable (SVGTextBox<text>.heavy) [138.65625,43.953125 148.234375x79.71875]
SVGPathPaintable (SVGTextBox<text>.small) [187.65625,153.703125 34.578125x34.703125]
SVGPathPaintable (SVGTextBox<text>.Rrrrr) [220.328125,83.15625 519.484375x115.359375]
SVGPathPaintable (SVGTextBox<text>.small) [76.40625,90.28125 46.46875x35.578125]
SVGPathPaintable (SVGTextBox<text>.heavy) [143.640625,58.21875 145.90625x65.453125]
SVGPathPaintable (SVGTextBox<text>.small) [190.359375,155.734375 32.84375x32.671875]
SVGPathPaintable (SVGTextBox<text>.Rrrrr) [226.96875,92.46875 514.125x106.03125]

View file

@ -12,13 +12,11 @@
height: 300px;
overflow-y: scroll;
background-color: #fff;
border: 10px solid blueviolet;
}
.rotated-box {
width: 100px;
height: 100px;
margin: 10px;
border: 5px solid magenta;
background-color: #3498db;
overflow: hidden;
}

View file

@ -12,13 +12,11 @@
height: 300px;
overflow-y: scroll;
background-color: #fff;
border: 10px solid blueviolet;
}
.rotated-box {
width: 100px;
height: 100px;
margin: 10px;
border: 5px solid magenta;
background-color: #3498db;
transform: rotate(90deg);
overflow: hidden;

View file

@ -42,6 +42,7 @@ public:
virtual NonnullOwnPtr<PathImpl> clone() const = 0;
virtual NonnullOwnPtr<PathImpl> copy_transformed(Gfx::AffineTransform const&) const = 0;
virtual NonnullOwnPtr<PathImpl> place_text_along(Utf8View text, Font const&) const = 0;
};
class Path {
@ -74,6 +75,9 @@ public:
void cubic_bezier_curve_to(FloatPoint c1, FloatPoint c2, FloatPoint p2) { impl().cubic_bezier_curve_to(c1, c2, p2); }
void text(Utf8View text, Font const& font) { impl().text(text, font); }
void horizontal_line_to(float x) { line_to({ x, last_point().y() }); }
void vertical_line_to(float y) { line_to({ last_point().x(), y }); }
void append_path(Gfx::Path const& other) { impl().append_path(other); }
void intersect(Gfx::Path const& other) { impl().intersect(other); }
@ -83,6 +87,7 @@ public:
Gfx::Path clone() const { return Gfx::Path { impl().clone() }; }
Gfx::Path copy_transformed(Gfx::AffineTransform const& transform) const { return Gfx::Path { impl().copy_transformed(transform) }; }
Gfx::Path place_text_along(Utf8View text, Font const& font) const { return Gfx::Path { impl().place_text_along(text, font) }; }
void transform(Gfx::AffineTransform const& transform) { m_impl = impl().copy_transformed(transform); }

View file

@ -9,8 +9,11 @@
#include <AK/TypeCasts.h>
#include <LibGfx/Font/ScaledFont.h>
#include <LibGfx/PathSkia.h>
#include <core/SkContourMeasure.h>
#include <core/SkFont.h>
#include <core/SkPath.h>
#include <core/SkPathMeasure.h>
#include <core/SkTextBlob.h>
#include <pathops/SkPathOps.h>
#include <utils/SkTextUtils.h>
@ -129,6 +132,43 @@ void PathImplSkia::text(Utf8View string, Font const& font)
{
SkTextUtils::GetPath(string.as_string().characters_without_null_termination(), string.as_string().length(), SkTextEncoding::kUTF8, last_point().x(), last_point().y(), verify_cast<ScaledFont>(font).skia_font(1), m_path.ptr());
}
NonnullOwnPtr<PathImpl> PathImplSkia::place_text_along(Utf8View text, Font const& font) const
{
auto sk_font = verify_cast<ScaledFont>(font).skia_font(1);
size_t const text_length = text.length();
SkScalar x = 0;
SkScalar y = 0;
SkTextBlobBuilder builder;
SkTextBlobBuilder::RunBuffer runBuffer = builder.allocRun(sk_font, text_length, x, y, nullptr);
sk_font.textToGlyphs(text.as_string().characters_without_null_termination(), text.as_string().length(), SkTextEncoding::kUTF8, runBuffer.glyphs, text_length);
SkPathMeasure pathMeasure(*m_path, false);
SkScalar accumulated_distance = 0;
auto output_path = PathImplSkia::create();
for (size_t i = 0; i < text_length; ++i) {
SkGlyphID glyph = runBuffer.glyphs[i];
SkPath glyphPath;
sk_font.getPath(glyph, &glyphPath);
SkScalar advance;
sk_font.getWidths(&glyph, 1, &advance);
SkPoint position;
SkVector tangent;
if (!pathMeasure.getPosTan(accumulated_distance, &position, &tangent))
continue;
SkMatrix matrix;
matrix.setTranslate(position.x(), position.y());
matrix.preRotate(SkRadiansToDegrees(std::atan2(tangent.y(), tangent.x())));
glyphPath.transform(matrix);
output_path->sk_path().addPath(glyphPath);
accumulated_distance += advance;
}
return output_path;
}
void PathImplSkia::append_path(Gfx::Path const& other)
{

View file

@ -38,6 +38,7 @@ public:
virtual NonnullOwnPtr<PathImpl> clone() const override;
virtual NonnullOwnPtr<PathImpl> copy_transformed(Gfx::AffineTransform const&) const override;
virtual NonnullOwnPtr<PathImpl> place_text_along(Utf8View text, Font const&) const override;
SkPath const& sk_path() const { return *m_path; }
SkPath& sk_path() { return *m_path; }

View file

@ -7,6 +7,7 @@
#pragma once
#include <AK/HashMap.h>
#include <LibGfx/Path.h>
#include <LibGfx/Point.h>
#include <LibWeb/Layout/Box.h>
#include <LibWeb/Layout/LineBox.h>
@ -132,7 +133,7 @@ struct LayoutState {
void set_table_cell_coordinates(Painting::PaintableBox::TableCellCoordinates const& table_cell_coordinates) { m_table_cell_coordinates = table_cell_coordinates; }
auto const& table_cell_coordinates() const { return m_table_cell_coordinates; }
void set_computed_svg_path(Gfx::DeprecatedPath const& svg_path) { m_computed_svg_path = svg_path; }
void set_computed_svg_path(Gfx::Path const& svg_path) { m_computed_svg_path = svg_path; }
auto& computed_svg_path() { return m_computed_svg_path; }
void set_computed_svg_transforms(Painting::SVGGraphicsPaintable::ComputedTransforms const& computed_transforms) { m_computed_svg_transforms = computed_transforms; }
@ -163,7 +164,7 @@ struct LayoutState {
Optional<Painting::PaintableBox::BordersDataWithElementKind> m_override_borders_data;
Optional<Painting::PaintableBox::TableCellCoordinates> m_table_cell_coordinates;
Optional<Gfx::DeprecatedPath> m_computed_svg_path;
Optional<Gfx::Path> m_computed_svg_path;
Optional<Painting::SVGGraphicsPaintable::ComputedTransforms> m_computed_svg_transforms;
};

View file

@ -10,6 +10,7 @@
#include <AK/Debug.h>
#include <LibGfx/BoundingBox.h>
#include <LibGfx/Font/ScaledFont.h>
#include <LibGfx/Path.h>
#include <LibGfx/TextLayout.h>
#include <LibWeb/Layout/BlockFormattingContext.h>
#include <LibWeb/Layout/SVGClipBox.h>
@ -301,7 +302,7 @@ void SVGFormattingContext::layout_nested_viewport(Box const& viewport)
nested_context.run(static_cast<Box const&>(viewport), LayoutMode::Normal, *m_available_space);
}
Gfx::DeprecatedPath SVGFormattingContext::compute_path_for_text(SVGTextBox const& text_box)
Gfx::Path SVGFormattingContext::compute_path_for_text(SVGTextBox const& text_box)
{
auto& text_element = static_cast<SVG::SVGTextPositioningElement const&>(text_box.dom_node());
auto& font = text_box.first_available_font();
@ -333,13 +334,13 @@ Gfx::DeprecatedPath SVGFormattingContext::compute_path_for_text(SVGTextBox const
VERIFY_NOT_REACHED();
}
Gfx::DeprecatedPath path;
Gfx::Path path;
path.move_to(text_offset);
path.text(text_utf8, font);
return path;
}
Gfx::DeprecatedPath SVGFormattingContext::compute_path_for_text_path(SVGTextPathBox const& text_path_box)
Gfx::Path SVGFormattingContext::compute_path_for_text_path(SVGTextPathBox const& text_path_box)
{
auto& text_path_element = static_cast<SVG::SVGTextPathElement const&>(text_path_box.dom_node());
auto path_or_shape = text_path_element.path_or_shape();
@ -363,7 +364,7 @@ void SVGFormattingContext::layout_path_like_element(SVGGraphicsBox const& graphi
.multiply(m_current_viewbox_transform)
.multiply(graphics_box_state.computed_svg_transforms()->svg_transform());
Gfx::DeprecatedPath path;
Gfx::Path path;
if (is<SVGGeometryBox>(graphics_box)) {
auto& geometry_box = static_cast<SVGGeometryBox const&>(graphics_box);
path = const_cast<SVGGeometryBox&>(geometry_box).dom_node().get_path(m_viewport_size);

View file

@ -32,8 +32,8 @@ private:
void layout_path_like_element(SVGGraphicsBox const&);
void layout_mask_or_clip(SVGBox const&);
Gfx::DeprecatedPath compute_path_for_text(SVGTextBox const&);
Gfx::DeprecatedPath compute_path_for_text_path(SVGTextPathBox const&);
[[nodiscard]] Gfx::Path compute_path_for_text(SVGTextBox const&);
[[nodiscard]] Gfx::Path compute_path_for_text_path(SVGTextPathBox const&);
Gfx::AffineTransform m_parent_viewbox_transform {};

View file

@ -61,7 +61,7 @@ Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_
return border_data.color;
}
void paint_border(DisplayListRecorder& painter, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::DeprecatedPath& path, bool last)
void paint_border(DisplayListRecorder& 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) {
@ -553,7 +553,7 @@ void paint_all_borders(DisplayListRecorder& painter, DevicePixelRect const& bord
borders.enqueue(borders.dequeue());
}
Gfx::DeprecatedPath path;
Gfx::Path path;
for (BorderEdge edge : borders) {
switch (edge) {
case BorderEdge::Top:

View file

@ -26,7 +26,7 @@ enum class BorderEdge {
// Returns OptionalNone if there is no outline to paint.
Optional<BordersData> borders_data_for_outline(Layout::Node const&, Color outline_color, CSS::OutlineStyle outline_style, CSSPixels outline_width);
void paint_border(DisplayListRecorder& painter, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::DeprecatedPath& path, bool last);
void paint_border(DisplayListRecorder& painter, BorderEdge edge, DevicePixelRect const& rect, Gfx::AntiAliasingPainter::CornerRadius const& radius, Gfx::AntiAliasingPainter::CornerRadius const& opposite_radius, BordersDataDevicePixels const& borders_data, Gfx::Path&, bool last);
void paint_all_borders(DisplayListRecorder& painter, DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const&);
Gfx::Color border_color(BorderEdge edge, BordersDataDevicePixels const& borders_data);

View file

@ -18,9 +18,9 @@ namespace Web::Painting {
JS_DEFINE_ALLOCATOR(CheckBoxPaintable);
static Gfx::DeprecatedPath check_mark_path(Gfx::IntRect checkbox_rect)
static Gfx::Path check_mark_path(Gfx::IntRect checkbox_rect)
{
Gfx::DeprecatedPath path;
Gfx::Path path;
path.move_to({ 72, 14 });
path.line_to({ 37, 64 });
path.line_to({ 19, 47 });

View file

@ -18,6 +18,7 @@
#include <LibGfx/ImmutableBitmap.h>
#include <LibGfx/PaintStyle.h>
#include <LibGfx/Palette.h>
#include <LibGfx/Path.h>
#include <LibGfx/Point.h>
#include <LibGfx/Rect.h>
#include <LibGfx/ScalingMode.h>
@ -178,7 +179,7 @@ struct FillRectWithRoundedCorners {
struct FillPathUsingColor {
Gfx::IntRect path_bounding_rect;
Gfx::DeprecatedPath path;
Gfx::Path path;
Color color;
Gfx::WindingRule winding_rule;
Gfx::FloatPoint aa_translation;
@ -194,7 +195,7 @@ struct FillPathUsingColor {
struct FillPathUsingPaintStyle {
Gfx::IntRect path_bounding_rect;
Gfx::DeprecatedPath path;
Gfx::Path path;
PaintStyle paint_style;
Gfx::WindingRule winding_rule;
float opacity;
@ -211,7 +212,7 @@ struct FillPathUsingPaintStyle {
struct StrokePathUsingColor {
Gfx::IntRect path_bounding_rect;
Gfx::DeprecatedPath path;
Gfx::Path path;
Color color;
float thickness;
Gfx::FloatPoint aa_translation;
@ -227,7 +228,7 @@ struct StrokePathUsingColor {
struct StrokePathUsingPaintStyle {
Gfx::IntRect path_bounding_rect;
Gfx::DeprecatedPath path;
Gfx::Path path;
PaintStyle paint_style;
float thickness;
float opacity = 1.0f;

View file

@ -24,6 +24,7 @@
#include <pathops/SkPathOps.h>
#include <LibGfx/Font/ScaledFont.h>
#include <LibGfx/PathSkia.h>
#include <LibWeb/CSS/ComputedValues.h>
#include <LibWeb/Painting/DisplayListPlayerSkia.h>
#include <LibWeb/Painting/ShadowPainting.h>
@ -237,57 +238,9 @@ static SkColor4f to_skia_color4f(Gfx::Color const& color)
};
}
static SkPath to_skia_path(Gfx::DeprecatedPath const& path)
static SkPath to_skia_path(Gfx::Path const& path)
{
Optional<Gfx::FloatPoint> subpath_start_point;
Optional<Gfx::FloatPoint> subpath_last_point;
SkPathBuilder path_builder;
auto close_subpath_if_needed = [&](auto last_point) {
if (subpath_start_point == last_point)
path_builder.close();
};
for (auto const& segment : path) {
auto point = segment.point();
switch (segment.command()) {
case Gfx::DeprecatedPathSegment::Command::MoveTo: {
if (subpath_start_point.has_value() && subpath_last_point.has_value())
close_subpath_if_needed(subpath_last_point.value());
subpath_start_point = point;
path_builder.moveTo({ point.x(), point.y() });
break;
}
case Gfx::DeprecatedPathSegment::Command::LineTo: {
if (!subpath_start_point.has_value())
subpath_start_point = Gfx::FloatPoint { 0.0f, 0.0f };
path_builder.lineTo({ point.x(), point.y() });
break;
}
case Gfx::DeprecatedPathSegment::Command::QuadraticBezierCurveTo: {
if (!subpath_start_point.has_value())
subpath_start_point = Gfx::FloatPoint { 0.0f, 0.0f };
SkPoint pt1 = { segment.through().x(), segment.through().y() };
SkPoint pt2 = { segment.point().x(), segment.point().y() };
path_builder.quadTo(pt1, pt2);
break;
}
case Gfx::DeprecatedPathSegment::Command::CubicBezierCurveTo: {
if (!subpath_start_point.has_value())
subpath_start_point = Gfx::FloatPoint { 0.0f, 0.0f };
SkPoint pt1 = { segment.through_0().x(), segment.through_0().y() };
SkPoint pt2 = { segment.through_1().x(), segment.through_1().y() };
SkPoint pt3 = { segment.point().x(), segment.point().y() };
path_builder.cubicTo(pt1, pt2, pt3);
break;
}
default:
VERIFY_NOT_REACHED();
}
subpath_last_point = point;
}
close_subpath_if_needed(subpath_last_point);
return path_builder.snapshot();
return static_cast<Gfx::PathImplSkia const&>(path.impl()).sk_path();
}
static SkPathFillType to_skia_path_fill_type(Gfx::WindingRule winding_rule)

View file

@ -62,7 +62,7 @@ void DisplayListRecorder::fill_path(FillPathUsingColorParams params)
return;
append(FillPathUsingColor {
.path_bounding_rect = path_bounding_rect,
.path = params.path,
.path = move(params.path),
.color = params.color,
.winding_rule = params.winding_rule,
.aa_translation = aa_translation,
@ -77,7 +77,7 @@ void DisplayListRecorder::fill_path(FillPathUsingPaintStyleParams params)
return;
append(FillPathUsingPaintStyle {
.path_bounding_rect = path_bounding_rect,
.path = params.path,
.path = move(params.path),
.paint_style = params.paint_style,
.winding_rule = params.winding_rule,
.opacity = params.opacity,
@ -95,7 +95,7 @@ void DisplayListRecorder::stroke_path(StrokePathUsingColorParams params)
return;
append(StrokePathUsingColor {
.path_bounding_rect = path_bounding_rect,
.path = params.path,
.path = move(params.path),
.color = params.color,
.thickness = params.thickness,
.aa_translation = aa_translation,
@ -112,7 +112,7 @@ void DisplayListRecorder::stroke_path(StrokePathUsingPaintStyleParams params)
return;
append(StrokePathUsingPaintStyle {
.path_bounding_rect = path_bounding_rect,
.path = params.path,
.path = move(params.path),
.paint_style = params.paint_style,
.thickness = params.thickness,
.opacity = params.opacity,

View file

@ -18,6 +18,7 @@
#include <LibGfx/ImmutableBitmap.h>
#include <LibGfx/PaintStyle.h>
#include <LibGfx/Palette.h>
#include <LibGfx/Path.h>
#include <LibGfx/Point.h>
#include <LibGfx/Rect.h>
#include <LibGfx/ScalingMode.h>
@ -43,7 +44,7 @@ public:
void fill_rect(Gfx::IntRect const& rect, Color color);
struct FillPathUsingColorParams {
Gfx::DeprecatedPath path;
Gfx::Path path;
Gfx::Color color;
Gfx::WindingRule winding_rule = Gfx::WindingRule::EvenOdd;
Optional<Gfx::FloatPoint> translation = {};
@ -51,7 +52,7 @@ public:
void fill_path(FillPathUsingColorParams params);
struct FillPathUsingPaintStyleParams {
Gfx::DeprecatedPath path;
Gfx::Path path;
PaintStyle paint_style;
Gfx::WindingRule winding_rule = Gfx::WindingRule::EvenOdd;
float opacity;
@ -60,7 +61,7 @@ public:
void fill_path(FillPathUsingPaintStyleParams params);
struct StrokePathUsingColorParams {
Gfx::DeprecatedPath path;
Gfx::Path path;
Gfx::Color color;
float thickness;
Optional<Gfx::FloatPoint> translation = {};
@ -68,7 +69,7 @@ public:
void stroke_path(StrokePathUsingColorParams params);
struct StrokePathUsingPaintStyleParams {
Gfx::DeprecatedPath path;
Gfx::Path path;
PaintStyle paint_style;
float thickness;
float opacity;

View file

@ -83,7 +83,7 @@ void MarkerPaintable::paint(PaintContext& context, PaintPhase phase) const
// FIXME: If the image is directional, it must respond to the writing mode of the element, similar to the bidi-sensitive images feature of the Images 4 module.
// Draw an equilateral triangle pointing right.
auto path = Gfx::DeprecatedPath();
auto path = Gfx::Path();
path.move_to({ left, top });
path.line_to({ left + sin_60_deg * (right - left), (top + bottom) / 2 });
path.line_to({ left, bottom });
@ -97,7 +97,7 @@ void MarkerPaintable::paint(PaintContext& context, PaintPhase phase) const
// FIXME: If the image is directional, it must respond to the writing mode of the element, similar to the bidi-sensitive images feature of the Images 4 module.
// Draw an equilateral triangle pointing down.
auto path = Gfx::DeprecatedPath();
auto path = Gfx::Path();
path.move_to({ left, top });
path.line_to({ right, top });
path.line_to({ (left + right) / 2, top + sin_60_deg * (bottom - top) });

View file

@ -46,7 +46,7 @@ Optional<DevicePixelPoint> MediaPaintable::mouse_position(PaintContext& context,
void MediaPaintable::fill_triangle(DisplayListRecorder& painter, Gfx::IntPoint location, Array<Gfx::IntPoint, 3> coordinates, Color color)
{
Gfx::DeprecatedPath path;
Gfx::Path path;
path.move_to((coordinates[0] + location).to_type<float>());
path.line_to((coordinates[1] + location).to_type<float>());
path.line_to((coordinates[2] + location).to_type<float>());
@ -217,7 +217,7 @@ void MediaPaintable::paint_control_bar_speaker(PaintContext& context, HTML::HTML
auto speaker_button_is_hovered = rect_is_hovered(media_element, components.speaker_button_rect, mouse_position);
auto speaker_button_color = control_button_color(speaker_button_is_hovered);
Gfx::DeprecatedPath path;
Gfx::Path path;
path.move_to(device_point(0, 4));
path.line_to(device_point(5, 4));

View file

@ -72,7 +72,7 @@ void SVGPathPaintable::paint(PaintContext& context, PaintPhase phase) const
auto maybe_view_box = svg_node->dom_node().view_box();
auto paint_transform = computed_transforms().svg_to_device_pixels_transform(context);
Gfx::DeprecatedPath path = computed_path()->copy_transformed(paint_transform);
auto path = computed_path()->copy_transformed(paint_transform);
// Fills are computed as though all subpaths are closed (https://svgwg.org/svg2-draft/painting.html#FillProperties)
auto closed_path = [&] {

View file

@ -6,6 +6,7 @@
#pragma once
#include <LibGfx/Path.h>
#include <LibWeb/Layout/SVGGraphicsBox.h>
#include <LibWeb/Painting/SVGGraphicsPaintable.h>
@ -24,17 +25,17 @@ public:
Layout::SVGGraphicsBox const& layout_box() const;
void set_computed_path(Gfx::DeprecatedPath path)
void set_computed_path(Gfx::Path path)
{
m_computed_path = move(path);
}
Optional<Gfx::DeprecatedPath> const& computed_path() const { return m_computed_path; }
Optional<Gfx::Path> const& computed_path() const { return m_computed_path; }
protected:
SVGPathPaintable(Layout::SVGGraphicsBox const&);
Optional<Gfx::DeprecatedPath> m_computed_path = {};
Optional<Gfx::Path> m_computed_path = {};
};
}

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/Path.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/SVGCircleElementPrototype.h>
#include <LibWeb/CSS/Parser/Parser.h>
@ -46,7 +47,7 @@ void SVGCircleElement::apply_presentational_hints(CSS::StyleProperties& style) c
style.set_property(CSS::PropertyID::R, r_value.release_nonnull());
}
Gfx::DeprecatedPath SVGCircleElement::get_path(CSSPixelSize viewport_size)
Gfx::Path SVGCircleElement::get_path(CSSPixelSize viewport_size)
{
auto node = layout_node();
auto cx = float(node->computed_values().cx().to_px(*node, viewport_size.width()));
@ -59,7 +60,7 @@ Gfx::DeprecatedPath SVGCircleElement::get_path(CSSPixelSize viewport_size)
if (r == 0)
return {};
Gfx::DeprecatedPath path;
Gfx::Path path;
bool large_arc = false;
bool sweep = true;

View file

@ -20,7 +20,7 @@ public:
virtual void apply_presentational_hints(CSS::StyleProperties&) const override;
virtual Gfx::DeprecatedPath get_path(CSSPixelSize viewport_size) override;
virtual Gfx::Path get_path(CSSPixelSize viewport_size) override;
JS::NonnullGCPtr<SVGAnimatedLength> cx() const;
JS::NonnullGCPtr<SVGAnimatedLength> cy() const;

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/Path.h>
#include <LibWeb/Bindings/SVGEllipseElementPrototype.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/SVG/AttributeNames.h>
@ -40,13 +41,13 @@ void SVGEllipseElement::attribute_changed(FlyString const& name, Optional<String
}
}
Gfx::DeprecatedPath SVGEllipseElement::get_path(CSSPixelSize)
Gfx::Path SVGEllipseElement::get_path(CSSPixelSize)
{
float rx = m_radius_x.value_or(0);
float ry = m_radius_y.value_or(0);
float cx = m_center_x.value_or(0);
float cy = m_center_y.value_or(0);
Gfx::DeprecatedPath path;
Gfx::Path path;
// A computed value of zero for either dimension, or a computed value of auto for both dimensions, disables rendering of the element.
if (rx == 0 || ry == 0)

View file

@ -20,7 +20,7 @@ public:
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value) override;
virtual Gfx::DeprecatedPath get_path(CSSPixelSize viewport_size) override;
virtual Gfx::Path get_path(CSSPixelSize viewport_size) override;
JS::NonnullGCPtr<SVGAnimatedLength> cx() const;
JS::NonnullGCPtr<SVGAnimatedLength> cy() const;

View file

@ -18,7 +18,7 @@ class SVGGeometryElement : public SVGGraphicsElement {
public:
virtual JS::GCPtr<Layout::Node> create_layout_node(NonnullRefPtr<CSS::StyleProperties>) override;
virtual Gfx::DeprecatedPath get_path(CSSPixelSize viewport_size) = 0;
virtual Gfx::Path get_path(CSSPixelSize viewport_size) = 0;
float get_total_length();
JS::NonnullGCPtr<Geometry::DOMPoint> get_point_at_length(float distance);

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/Path.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/SVGLineElementPrototype.h>
#include <LibWeb/SVG/AttributeNames.h>
@ -40,12 +41,12 @@ void SVGLineElement::attribute_changed(FlyString const& name, Optional<String> c
}
}
Gfx::DeprecatedPath SVGLineElement::get_path(CSSPixelSize viewport_size)
Gfx::Path SVGLineElement::get_path(CSSPixelSize viewport_size)
{
auto const viewport_width = viewport_size.width().to_float();
auto const viewport_height = viewport_size.height().to_float();
Gfx::DeprecatedPath path;
Gfx::Path path;
float const x1 = m_x1.value_or({ 0, false }).resolve_relative_to(viewport_width);
float const y1 = m_y1.value_or({ 0, false }).resolve_relative_to(viewport_height);
float const x2 = m_x2.value_or({ 0, false }).resolve_relative_to(viewport_width);

View file

@ -20,7 +20,7 @@ public:
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value) override;
virtual Gfx::DeprecatedPath get_path(CSSPixelSize viewport_size) override;
virtual Gfx::Path get_path(CSSPixelSize viewport_size) override;
JS::NonnullGCPtr<SVGAnimatedLength> x1() const;
JS::NonnullGCPtr<SVGAnimatedLength> y1() const;

View file

@ -105,10 +105,9 @@ void SVGPathElement::attribute_changed(FlyString const& name, Optional<String> c
m_instructions = AttributeParser::parse_path_data(value.value_or(String {}));
}
template<typename PathType>
PathType path_from_path_instructions(ReadonlySpan<PathInstruction> instructions)
Gfx::Path path_from_path_instructions(ReadonlySpan<PathInstruction> instructions)
{
PathType path;
Gfx::Path path;
Optional<Gfx::FloatPoint> previous_control_point;
PathInstructionType last_instruction = PathInstructionType::Invalid;
@ -274,19 +273,9 @@ PathType path_from_path_instructions(ReadonlySpan<PathInstruction> instructions)
return path;
}
Gfx::Path path_from_path_instructions(ReadonlySpan<PathInstruction> instructions)
Gfx::Path SVGPathElement::get_path(CSSPixelSize)
{
return path_from_path_instructions<Gfx::Path>(instructions);
}
Gfx::DeprecatedPath deprecated_path_from_path_instructions(ReadonlySpan<PathInstruction> instructions)
{
return path_from_path_instructions<Gfx::DeprecatedPath>(instructions);
}
Gfx::DeprecatedPath SVGPathElement::get_path(CSSPixelSize)
{
return deprecated_path_from_path_instructions(m_instructions);
return path_from_path_instructions(m_instructions);
}
}

View file

@ -22,7 +22,7 @@ public:
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value) override;
virtual Gfx::DeprecatedPath get_path(CSSPixelSize viewport_size) override;
virtual Gfx::Path get_path(CSSPixelSize viewport_size) override;
private:
SVGPathElement(DOM::Document&, DOM::QualifiedName);
@ -33,6 +33,5 @@ private:
};
[[nodiscard]] Gfx::Path path_from_path_instructions(ReadonlySpan<PathInstruction>);
[[nodiscard]] Gfx::DeprecatedPath deprecated_path_from_path_instructions(ReadonlySpan<PathInstruction>);
}

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/Path.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/SVGPolygonElementPrototype.h>
#include <LibWeb/SVG/AttributeNames.h>
@ -33,9 +34,9 @@ void SVGPolygonElement::attribute_changed(FlyString const& name, Optional<String
m_points = AttributeParser::parse_points(value.value_or(String {}));
}
Gfx::DeprecatedPath SVGPolygonElement::get_path(CSSPixelSize)
Gfx::Path SVGPolygonElement::get_path(CSSPixelSize)
{
Gfx::DeprecatedPath path;
Gfx::Path path;
if (m_points.is_empty())
return path;

View file

@ -19,7 +19,7 @@ public:
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value) override;
virtual Gfx::DeprecatedPath get_path(CSSPixelSize viewport_size) override;
virtual Gfx::Path get_path(CSSPixelSize viewport_size) override;
private:
SVGPolygonElement(DOM::Document&, DOM::QualifiedName);

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/Path.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/SVGPolylineElementPrototype.h>
#include <LibWeb/SVG/AttributeNames.h>
@ -33,9 +34,9 @@ void SVGPolylineElement::attribute_changed(FlyString const& name, Optional<Strin
m_points = AttributeParser::parse_points(value.value_or(String {}));
}
Gfx::DeprecatedPath SVGPolylineElement::get_path(CSSPixelSize)
Gfx::Path SVGPolylineElement::get_path(CSSPixelSize)
{
Gfx::DeprecatedPath path;
Gfx::Path path;
if (m_points.is_empty())
return path;

View file

@ -19,7 +19,7 @@ public:
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value) override;
virtual Gfx::DeprecatedPath get_path(CSSPixelSize viewport_size) override;
virtual Gfx::Path get_path(CSSPixelSize viewport_size) override;
private:
SVGPolylineElement(DOM::Document&, DOM::QualifiedName);

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/Path.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/SVGRectElementPrototype.h>
#include <LibWeb/SVG/AttributeNames.h>
@ -46,14 +47,14 @@ void SVGRectElement::attribute_changed(FlyString const& name, Optional<String> c
}
}
Gfx::DeprecatedPath SVGRectElement::get_path(CSSPixelSize)
Gfx::Path SVGRectElement::get_path(CSSPixelSize)
{
float width = m_width.value_or(0);
float height = m_height.value_or(0);
float x = m_x.value_or(0);
float y = m_y.value_or(0);
Gfx::DeprecatedPath path;
Gfx::Path path;
// If width or height is zero, rendering is disabled.
if (width == 0 || height == 0)
return path;
@ -106,6 +107,8 @@ Gfx::DeprecatedPath SVGRectElement::get_path(CSSPixelSize)
if (rx > 0 && ry > 0)
path.elliptical_arc_to({ x + rx, y }, corner_radii, x_axis_rotation, large_arc_flag, sweep_flag);
path.close();
return path;
}

View file

@ -20,7 +20,7 @@ public:
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value) override;
virtual Gfx::DeprecatedPath get_path(CSSPixelSize viewport_size) override;
virtual Gfx::Path get_path(CSSPixelSize viewport_size) override;
JS::NonnullGCPtr<SVGAnimatedLength> x() const;
JS::NonnullGCPtr<SVGAnimatedLength> y() const;