mirror of
https://github.com/servo/servo.git
synced 2025-08-10 16:05:43 +01:00
add implementation for Path2D addPath method (#37838)
Add implementation for Path2D addPath method Spec: https://html.spec.whatwg.org/multipage/canvas.html#dom-path2d-addpath Testing: WPT test - `tests/wpt/tests/css/geometry/DOMMatrix2DInit-validate-fixup.html` Fixes: #37695 --------- Signed-off-by: Lloyd Massiah <artmis9@protonmail.com> Signed-off-by: arthmis <artmis9@protonmail.com>
This commit is contained in:
parent
6471587fb4
commit
86d7f4c793
5 changed files with 57 additions and 83 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -7154,6 +7154,7 @@ dependencies = [
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"jstraceable_derive",
|
"jstraceable_derive",
|
||||||
"keyboard-types",
|
"keyboard-types",
|
||||||
|
"kurbo",
|
||||||
"layout_api",
|
"layout_api",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
|
|
@ -81,6 +81,7 @@ itertools = { workspace = true }
|
||||||
js = { workspace = true }
|
js = { workspace = true }
|
||||||
jstraceable_derive = { path = "../jstraceable_derive" }
|
jstraceable_derive = { path = "../jstraceable_derive" }
|
||||||
keyboard-types = { workspace = true }
|
keyboard-types = { workspace = true }
|
||||||
|
kurbo = { workspace = true }
|
||||||
layout_api = { workspace = true }
|
layout_api = { workspace = true }
|
||||||
libc = { workspace = true }
|
libc = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
|
|
@ -7,12 +7,15 @@ use std::cell::RefCell;
|
||||||
use canvas_traits::canvas::Path;
|
use canvas_traits::canvas::Path;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use js::rust::HandleObject;
|
use js::rust::HandleObject;
|
||||||
|
use script_bindings::codegen::GenericBindings::DOMMatrixBinding::DOMMatrix2DInit;
|
||||||
|
use script_bindings::error::ErrorResult;
|
||||||
use script_bindings::str::DOMString;
|
use script_bindings::str::DOMString;
|
||||||
|
|
||||||
use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::Path2DMethods;
|
use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::Path2DMethods;
|
||||||
use crate::dom::bindings::error::{Error, Fallible};
|
use crate::dom::bindings::error::{Error, Fallible};
|
||||||
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto};
|
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto};
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
|
use crate::dom::dommatrixreadonly::dommatrix2dinit_to_matrix;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::script_runtime::CanGc;
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
|
@ -48,14 +51,60 @@ impl Path2D {
|
||||||
pub(crate) fn segments(&self) -> Path {
|
pub(crate) fn segments(&self) -> Path {
|
||||||
self.path.borrow().clone()
|
self.path.borrow().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn is_path_empty(&self) -> bool {
|
||||||
|
self.path.borrow().0.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_path(&self, other: &Path2D, transform: &DOMMatrix2DInit) -> ErrorResult {
|
||||||
|
// Step 1. If the Path2D object path has no subpaths, then return.
|
||||||
|
if other.is_path_empty() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2 Let matrix be the result of creating a DOMMatrix from the 2D dictionary transform.
|
||||||
|
let matrix = dommatrix2dinit_to_matrix(transform)?;
|
||||||
|
|
||||||
|
// Step 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.
|
||||||
|
if !matrix.m11.is_finite() ||
|
||||||
|
!matrix.m12.is_finite() ||
|
||||||
|
!matrix.m21.is_finite() ||
|
||||||
|
!matrix.m22.is_finite() ||
|
||||||
|
!matrix.m31.is_finite() ||
|
||||||
|
!matrix.m32.is_finite()
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4. Create a copy of all the subpaths in path. Let c be this copy.
|
||||||
|
let mut c = other.segments();
|
||||||
|
|
||||||
|
// Step 5. Transform all the coordinates and lines in c by the transform matrix `matrix`.
|
||||||
|
c.transform(matrix);
|
||||||
|
|
||||||
|
let mut path = self.path.borrow_mut();
|
||||||
|
|
||||||
|
// Step 6. Let (x, y) be the last point in the last subpath of c
|
||||||
|
let last_point = path.last_point();
|
||||||
|
|
||||||
|
// Step 7. Add all the subpaths in c to a.
|
||||||
|
path.0.extend(c.0);
|
||||||
|
|
||||||
|
// Step 8. Create a new subpath in `a` with (x, y) as the only point in the subpath.
|
||||||
|
if let Some(last_point) = last_point {
|
||||||
|
path.move_to(last_point.x, last_point.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Path2DMethods<crate::DomTypeHolder> for Path2D {
|
impl Path2DMethods<crate::DomTypeHolder> for Path2D {
|
||||||
/// <https://html.spec.whatwg.org/multipage/#dom-path2d-addpath>
|
/// <https://html.spec.whatwg.org/multipage/#dom-path2d-addpath>
|
||||||
fn AddPath(&self, other: &Path2D) {
|
fn AddPath(&self, other: &Path2D, transform: &DOMMatrix2DInit) -> ErrorResult {
|
||||||
let other = other.segments();
|
self.add_path(other, transform)
|
||||||
// Step 7. Add all the subpaths in c to a.
|
|
||||||
self.path.borrow_mut().0.extend(other.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-closepath>
|
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-closepath>
|
||||||
|
|
|
@ -287,6 +287,7 @@ interface Path2D {
|
||||||
constructor();
|
constructor();
|
||||||
constructor(Path2D other);
|
constructor(Path2D other);
|
||||||
constructor(DOMString pathString);
|
constructor(DOMString pathString);
|
||||||
undefined addPath(Path2D path/*, SVGMatrix? transformation*/);
|
[Throws]
|
||||||
|
undefined addPath(Path2D path, optional DOMMatrix2DInit transform = {});
|
||||||
};
|
};
|
||||||
Path2D includes CanvasPath;
|
Path2D includes CanvasPath;
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
[DOMMatrix2DInit-validate-fixup.html]
|
|
||||||
[addPath({a: 1, m11: 2}) (invalid)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({b: 0, m12: -1}) (invalid)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({c: Infinity, m21: -Infinity}) (invalid)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({d: 0, m22: NaN}) (invalid)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({e: 1, m41: 1.00000001}) (invalid)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({f: 0, m42: 5e-324}) (invalid)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({d: Infinity, m22: Infinity})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({e: -Infinity, m41: -Infinity})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({f: NaN, m42: NaN})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({f: NaN, m42: NaN, is2D: true})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({a: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({b: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({c: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({d: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({e: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({f: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({a: -0, b: -0, c: -0, d: -0, e: -0, f: -0})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({a: -0, b: -0, c: -0, d: -0, e: -0, f: -0, is2D: true})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({m11: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({m12: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({m21: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({m22: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({m41: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({m42: 2})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0})]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[addPath({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0, is2D: true})]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue