/
githubmirror
/
servo
Обзор
Документация
Войти
/
githubmirror
/
servo
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
components/script/dom/canvas/2d/path2d.rs
226 строк
7 KB
Tim van der Lippe
script: Mechanically migrate to `reflect_dom_object_with_proto` (#46529)
15 июл 2026, 23:09
Не верифицирован
15 июл 2026, 23:09
2557009
Код
Авторство
О чём код?
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::cell::RefCell; use dom_struct::dom_struct; use js::context::JSContext; use js::rust::HandleObject; use script_bindings::codegen::GenericBindings::DOMMatrixBinding::DOMMatrix2DInit; use script_bindings::error::ErrorResult; use script_bindings::reflector::{Reflector, reflect_dom_object_with_proto}; use script_bindings::str::DOMString; use servo_canvas_traits::canvas::Path; use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::Path2DMethods; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::root::DomRoot; use crate::dom::dommatrixreadonly::dommatrix2dinit_to_matrix; use crate::dom::globalscope::GlobalScope; #[dom_struct] pub(crate) struct Path2D { reflector_: Reflector, #[ignore_malloc_size_of = "Defined in kurbo."] #[no_trace] path: RefCell<Path>, } impl Path2D { pub(crate) fn new() -> Path2D { Self { reflector_: Reflector::new(), path: RefCell::new(Path::new()), } } pub(crate) fn new_with_path(other: &Path2D) -> Path2D { Self { reflector_: Reflector::new(), path: other.path.clone(), } } pub(crate) fn new_with_str(path: &str) -> Path2D { Self { reflector_: Reflector::new(), path: RefCell::new(Path::from_svg(path)), } } pub(crate) fn segments(&self) -> Path { 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 { /// <https://html.spec.whatwg.org/multipage/#dom-path2d-addpath> fn AddPath(&self, other: &Path2D, transform: &DOMMatrix2DInit) -> ErrorResult { self.add_path(other, transform) } /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-closepath> fn ClosePath(&self) { self.path.borrow_mut().close_path(); } /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-moveto> fn MoveTo(&self, x: f64, y: f64) { self.path.borrow_mut().move_to(x, y); } /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-lineto> fn LineTo(&self, x: f64, y: f64) { self.path.borrow_mut().line_to(x, y); } /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-quadraticcurveto> fn QuadraticCurveTo(&self, cpx: f64, cpy: f64, x: f64, y: f64) { self.path.borrow_mut().quadratic_curve_to(cpx, cpy, x, y); } /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-beziercurveto> fn BezierCurveTo(&self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, x: f64, y: f64) { self.path .borrow_mut() .bezier_curve_to(cp1x, cp1y, cp2x, cp2y, x, y); } /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-arcto> fn ArcTo(&self, x1: f64, y1: f64, x2: f64, y2: f64, radius: f64) -> Fallible<()> { self.path .borrow_mut() .arc_to(x1, y1, x2, y2, radius) .map_err(|_| Error::IndexSize(None)) } /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-rect> fn Rect(&self, x: f64, y: f64, w: f64, h: f64) { self.path.borrow_mut().rect(x, y, w, h); } /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-arc> fn Arc( &self, x: f64, y: f64, radius: f64, start_angle: f64, end_angle: f64, counterclockwise: bool, ) -> Fallible<()> { self.path .borrow_mut() .arc(x, y, radius, start_angle, end_angle, counterclockwise) .map_err(|_| Error::IndexSize(None)) } /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-ellipse> fn Ellipse( &self, x: f64, y: f64, radius_x: f64, radius_y: f64, rotation_angle: f64, start_angle: f64, end_angle: f64, counterclockwise: bool, ) -> Fallible<()> { self.path .borrow_mut() .ellipse( x, y, radius_x, radius_y, rotation_angle, start_angle, end_angle, counterclockwise, ) .map_err(|_| Error::IndexSize(None)) } /// <https://html.spec.whatwg.org/multipage/#dom-path2d-dev> fn Constructor( cx: &mut JSContext, global: &GlobalScope, proto: Option<HandleObject>, ) -> DomRoot<Path2D> { reflect_dom_object_with_proto(cx, Box::new(Self::new()), global, proto) } /// <https://html.spec.whatwg.org/multipage/#dom-path2d-dev> fn Constructor_( cx: &mut JSContext, global: &GlobalScope, proto: Option<HandleObject>, other: &Path2D, ) -> DomRoot<Path2D> { reflect_dom_object_with_proto(cx, Box::new(Self::new_with_path(other)), global, proto) } /// <https://html.spec.whatwg.org/multipage/#dom-path2d-dev> fn Constructor__( cx: &mut JSContext, global: &GlobalScope, proto: Option<HandleObject>, path_string: DOMString, ) -> DomRoot<Path2D> { reflect_dom_object_with_proto( cx, Box::new(Self::new_with_str(&path_string.str())), global, proto, ) } }