Skip to content

Commit a964ebc

Browse files
Lubrsiawesomekling
authored andcommitted
LibWeb: Implement Path2D#addPath
Required by Ruffle.
1 parent 1f97adb commit a964ebc

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

Userland/Libraries/LibWeb/HTML/Path2D.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
/*
22
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
33
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
4+
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
45
*
56
* SPDX-License-Identifier: BSD-2-Clause
67
*/
78

89
#include <LibWeb/Bindings/Intrinsics.h>
10+
#include <LibWeb/Geometry/DOMMatrix.h>
911
#include <LibWeb/HTML/Path2D.h>
1012
#include <LibWeb/SVG/AttributeParser.h>
1113
#include <LibWeb/SVG/SVGPathElement.h>
@@ -62,4 +64,37 @@ JS::ThrowCompletionOr<void> Path2D::initialize(JS::Realm& realm)
6264
return {};
6365
}
6466

67+
// https://html.spec.whatwg.org/multipage/canvas.html#dom-path2d-addpath
68+
WebIDL::ExceptionOr<void> Path2D::add_path(JS::NonnullGCPtr<Path2D> path, Geometry::DOMMatrix2DInit& transform)
69+
{
70+
// The addPath(path, transform) method, when invoked on a Path2D object a, must run these steps:
71+
72+
// 1. If the Path2D object path has no subpaths, then return.
73+
if (path->path().segments().is_empty())
74+
return {};
75+
76+
// 2. Let matrix be the result of creating a DOMMatrix from the 2D dictionary transform.
77+
auto matrix = TRY(Geometry::DOMMatrix::create_from_dom_matrix_2d_init(realm(), transform));
78+
79+
// 3. If one or more of matrix's m11 element, m12 element, m21 element, m22 element, m41 element, or m42 element are infinite or NaN, then return.
80+
if (!isfinite(matrix->m11()) || !isfinite(matrix->m12()) || !isfinite(matrix->m21()) || !isfinite(matrix->m22()) || !isfinite(matrix->m41()) || !isfinite(matrix->m42()))
81+
return {};
82+
83+
// 4. Create a copy of all the subpaths in path. Let this copy be known as c.
84+
// 5. Transform all the coordinates and lines in c by the transform matrix matrix.
85+
auto copy = path->path().copy_transformed(Gfx::AffineTransform { static_cast<float>(matrix->m11()), static_cast<float>(matrix->m12()), static_cast<float>(matrix->m21()), static_cast<float>(matrix->m22()), static_cast<float>(matrix->m41()), static_cast<float>(matrix->m42()) });
86+
87+
// 6. Let (x, y) be the last point in the last subpath of c.
88+
auto xy = copy.segments().last().point();
89+
90+
// 7. Add all the subpaths in c to a.
91+
// FIXME: Is this correct?
92+
this->path().add_path(copy);
93+
94+
// 8. Create a new subpath in a with (x, y) as the only point in the subpath.
95+
this->move_to(xy.x(), xy.y());
96+
97+
return {};
98+
}
99+
65100
}

Userland/Libraries/LibWeb/HTML/Path2D.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <AK/RefCounted.h>
1010
#include <LibGfx/Path.h>
1111
#include <LibWeb/Bindings/PlatformObject.h>
12+
#include <LibWeb/Geometry/DOMMatrixReadOnly.h>
1213
#include <LibWeb/HTML/Canvas/CanvasPath.h>
1314

1415
namespace Web::HTML {
@@ -25,6 +26,8 @@ class Path2D final
2526

2627
virtual ~Path2D() override;
2728

29+
WebIDL::ExceptionOr<void> add_path(JS::NonnullGCPtr<Path2D> path, Geometry::DOMMatrix2DInit& transform);
30+
2831
private:
2932
Path2D(JS::Realm&, Optional<Variant<JS::Handle<Path2D>, DeprecatedString>> const&);
3033

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
#import <Geometry/DOMMatrixReadOnly.idl>
12
#import <HTML/Canvas/CanvasPath.idl>
23

34
// https://html.spec.whatwg.org/multipage/canvas.html#path2d
45
[Exposed=(Window,Worker)]
56
interface Path2D {
67
constructor(optional (Path2D or DOMString) path);
78

8-
// FIXME: undefined addPath(Path2D path, optional DOMMatrix2DInit transform = {});
9+
undefined addPath(Path2D path, optional DOMMatrix2DInit transform = {});
910
};
1011

1112
Path2D includes CanvasPath;

0 commit comments

Comments
 (0)