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:
parent
a3cc03f180
commit
137038b185
Notes:
github-actions[bot]
2024-08-20 07:38:12 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/137038b1850 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1024
37 changed files with 139 additions and 143 deletions
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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); }
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {};
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) });
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 = [&] {
|
||||
|
|
|
@ -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 = {};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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>);
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue