Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support DOMMatrix string constructor #23665

Merged
merged 1 commit into from Jul 2, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Support DOMMatrix string constructor

  • Loading branch information
saschanaz committed Jun 30, 2019
commit 7a1db0e8eaef9f615bedc08e23254bd79510de08
@@ -6,14 +6,17 @@ use crate::dom::bindings::codegen::Bindings::DOMMatrixBinding::{
DOMMatrixInit, DOMMatrixMethods, Wrap,
};
use crate::dom::bindings::codegen::Bindings::DOMMatrixReadOnlyBinding::DOMMatrixReadOnlyMethods;
use crate::dom::bindings::codegen::UnionTypes::StringOrUnrestrictedDoubleSequence;
use crate::dom::bindings::error;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::root::DomRoot;
use crate::dom::dommatrixreadonly::{
dommatrixinit_to_matrix, entries_to_matrix, DOMMatrixReadOnly,
dommatrixinit_to_matrix, entries_to_matrix, transform_to_matrix, DOMMatrixReadOnly,
};
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use euclid::Transform3D;
use js::rust::CustomAutoRooterGuard;
@@ -37,14 +40,32 @@ impl DOMMatrix {
}
}

// https://drafts.fxtf.org/geometry-1/#dom-dommatrix-dommatrix
pub fn Constructor(global: &GlobalScope) -> Fallible<DomRoot<Self>> {
Self::Constructor_(global, vec![1.0, 0.0, 0.0, 1.0, 0.0, 0.0])
}

// https://drafts.fxtf.org/geometry-1/#dom-dommatrix-dommatrix-numbersequence
pub fn Constructor_(global: &GlobalScope, entries: Vec<f64>) -> Fallible<DomRoot<Self>> {
entries_to_matrix(&entries[..]).map(|(is2D, matrix)| Self::new(global, is2D, matrix))
// https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-dommatrixreadonly
pub fn Constructor(
global: &GlobalScope,
init: Option<StringOrUnrestrictedDoubleSequence>,
) -> Fallible<DomRoot<Self>> {
if init.is_none() {
return Ok(Self::new(global, true, Transform3D::identity()));
}
match init.unwrap() {
StringOrUnrestrictedDoubleSequence::String(ref s) => {
if global.downcast::<Window>().is_none() {
return Err(error::Error::Type(
"String constructor is only supported in the main thread.".to_owned(),
));
}
if s.is_empty() {
return Ok(Self::new(global, true, Transform3D::identity()));
}
transform_to_matrix(s.to_string())
.map(|(is2D, matrix)| Self::new(global, is2D, matrix))
},
StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(ref entries) => {
entries_to_matrix(&entries[..])
.map(|(is2D, matrix)| Self::new(global, is2D, matrix))
},
}
}

// https://drafts.fxtf.org/geometry-1/#dom-dommatrix-frommatrix
@@ -62,7 +83,10 @@ impl DOMMatrix {
array: CustomAutoRooterGuard<Float32Array>,
) -> Fallible<DomRoot<DOMMatrix>> {
let vec: Vec<f64> = array.to_vec().iter().map(|&x| x as f64).collect();
DOMMatrix::Constructor_(global, vec)
DOMMatrix::Constructor(
global,
Some(StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(vec)),
)
}

// https://drafts.fxtf.org/geometry-1/#dom-dommatrix-fromfloat64array
@@ -71,7 +95,10 @@ impl DOMMatrix {
array: CustomAutoRooterGuard<Float64Array>,
) -> Fallible<DomRoot<DOMMatrix>> {
let vec: Vec<f64> = array.to_vec();
DOMMatrix::Constructor_(global, vec)
DOMMatrix::Constructor(
global,
Some(StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(vec)),
)
}
}

@@ -8,13 +8,17 @@ use crate::dom::bindings::codegen::Bindings::DOMMatrixReadOnlyBinding::{
DOMMatrixReadOnlyMethods, Wrap,
};
use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit;
use crate::dom::bindings::codegen::UnionTypes::StringOrUnrestrictedDoubleSequence;
use crate::dom::bindings::error;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::dommatrix::DOMMatrix;
use crate::dom::dompoint::DOMPoint;
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use cssparser::{Parser, ParserInput};
use dom_struct::dom_struct;
use euclid::{Angle, Transform3D};
use js::jsapi::{JSContext, JSObject};
@@ -25,6 +29,7 @@ use std::cell::{Cell, Ref};
use std::f64;
use std::ptr;
use std::ptr::NonNull;
use style::parser::ParserContext;

#[dom_struct]
pub struct DOMMatrixReadOnly {
@@ -49,13 +54,31 @@ impl DOMMatrixReadOnly {
}

// https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-dommatrixreadonly
pub fn Constructor(global: &GlobalScope) -> Fallible<DomRoot<Self>> {
Ok(Self::new(global, true, Transform3D::identity()))
}

// https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-dommatrixreadonly-numbersequence
pub fn Constructor_(global: &GlobalScope, entries: Vec<f64>) -> Fallible<DomRoot<Self>> {
entries_to_matrix(&entries[..]).map(|(is2D, matrix)| Self::new(global, is2D, matrix))
pub fn Constructor(
global: &GlobalScope,
init: Option<StringOrUnrestrictedDoubleSequence>,
) -> Fallible<DomRoot<Self>> {
if init.is_none() {
return Ok(Self::new(global, true, Transform3D::identity()));
}
match init.unwrap() {
StringOrUnrestrictedDoubleSequence::String(ref s) => {
if global.downcast::<Window>().is_none() {
return Err(error::Error::Type(
"String constructor is only supported in the main thread.".to_owned(),
));
}
if s.is_empty() {
return Ok(Self::new(global, true, Transform3D::identity()));
}
transform_to_matrix(s.to_string())
.map(|(is2D, matrix)| Self::new(global, is2D, matrix))
},
StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(ref entries) => {
entries_to_matrix(&entries[..])
.map(|(is2D, matrix)| Self::new(global, is2D, matrix))
},
}
}

// https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-frommatrix
@@ -372,7 +395,10 @@ impl DOMMatrixReadOnly {
array: CustomAutoRooterGuard<Float32Array>,
) -> Fallible<DomRoot<DOMMatrixReadOnly>> {
let vec: Vec<f64> = array.to_vec().iter().map(|&x| x as f64).collect();
DOMMatrixReadOnly::Constructor_(global, vec)
DOMMatrixReadOnly::Constructor(
global,
Some(StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(vec)),
)
}

// https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-fromfloat64array
@@ -382,7 +408,10 @@ impl DOMMatrixReadOnly {
array: CustomAutoRooterGuard<Float64Array>,
) -> Fallible<DomRoot<DOMMatrixReadOnly>> {
let vec: Vec<f64> = array.to_vec();
DOMMatrixReadOnly::Constructor_(global, vec)
DOMMatrixReadOnly::Constructor(
global,
Some(StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(vec)),
)
}
}

@@ -759,3 +788,32 @@ fn normalize_point(x: f64, y: f64, z: f64) -> (f64, f64, f64) {
(x / len, y / len, z / len)
}
}

pub fn transform_to_matrix(value: String) -> Fallible<(bool, Transform3D<f64>)> {
use style::properties::longhands::transform;

let mut input = ParserInput::new(&value);
let mut parser = Parser::new(&mut input);
let url = ::servo_url::ServoUrl::parse("about:blank").unwrap();
let context = ParserContext::new(
::style::stylesheets::Origin::Author,
&url,
Some(::style::stylesheets::CssRuleType::Style),
::style_traits::ParsingMode::DEFAULT,
::style::context::QuirksMode::NoQuirks,
None,
None,
);

let transform = match parser.parse_entirely(|t| transform::parse(&context, t)) {
Ok(result) => result,
Err(..) => return Err(error::Error::Syntax),
};

let (m, is_3d) = match transform.to_transform_3d_matrix_f64(None) {
Ok(result) => result,
Err(..) => return Err(error::Error::Syntax),
};

Ok((!is_3d, m))
}
@@ -10,9 +10,7 @@
* related or neighboring rights to this work.
*/

[Constructor,
// Constructor(DOMString transformList),
Constructor(sequence<unrestricted double> numberSequence),
[Constructor(optional (DOMString or sequence<unrestricted double>) init),
Exposed=(Window,Worker)]
interface DOMMatrix : DOMMatrixReadOnly {

@@ -10,9 +10,7 @@
* related or neighboring rights to this work.
*/

[Constructor,
// Constructor(DOMString transformList)
Constructor(sequence<unrestricted double> numberSequence),
[Constructor(optional (DOMString or sequence<unrestricted double>) init),
Exposed=(Window,Worker)]
interface DOMMatrixReadOnly {

@@ -542,6 +542,19 @@ impl<T: ToMatrix> Transform<T> {
)
};

let (m, is_3d) = match self.to_transform_3d_matrix_f64(reference_box) {
Ok(result) => result,
Err(err) => return Err(err),
};

Ok((cast_3d_transform(m), is_3d))
}

/// Same as Transform::to_transform_3d_matrix but a f64 version.
pub fn to_transform_3d_matrix_f64(
&self,
reference_box: Option<&Rect<Au>>,
) -> Result<(Transform3D<f64>, bool), ()> {
// We intentionally use Transform3D<f64> during computation to avoid error propagation
// because using f32 to compute triangle functions (e.g. in create_rotation()) is not
// accurate enough. In Gecko, we also use "double" to compute the triangle functions.
@@ -556,7 +569,7 @@ impl<T: ToMatrix> Transform<T> {
transform = transform.pre_mul(&matrix);
}

Ok((cast_3d_transform(transform), contain_3d))
Ok((transform, contain_3d))
}
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.