style: Define offset-path and implement it in style system.

Define OffsetPath & SVGPathData on the servo-side, and StyleMotion &
StyleSVGPath on the gecko-side. We parse the SVG Path string into a
vector of PathCommand. To build the gfx::Path, we will convert it into
gfx::Path later in a different patch.

The basic flow is:
  - Parse SVG Path String into SVGPathData (in Rust).
  - Use cbindgen to make sure the layout of PathCommand and StylePathCommand, and then set the Box[PathCommand] into nsTArray<StylePathCommand>.
  - Try to convert nsTArray<StylePathCommand> into gfx::Path. (This part will be implemented in a different patch.)

Finally, we use the gfx::Path to create a motion path transform.
The layout implementation is in the later patch.

Depends on D2962

Differential Revision: https://phabricator.services.mozilla.com/D2963
This commit is contained in:
Boris Chiou 2018-08-22 01:24:13 +00:00 committed by Emilio Cobos Álvarez
parent 249b865eb8
commit dce2e2927f
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
8 changed files with 742 additions and 3 deletions

View file

@ -3053,7 +3053,7 @@ fn static_assert() {
scroll-snap-points-x scroll-snap-points-y
scroll-snap-type-x scroll-snap-type-y scroll-snap-coordinate
perspective-origin -moz-binding will-change
overscroll-behavior-x overscroll-behavior-y
offset-path overscroll-behavior-x overscroll-behavior-y
overflow-clip-box-inline overflow-clip-box-block
perspective-origin -moz-binding will-change
shape-outside contain touch-action translate
@ -3681,6 +3681,51 @@ fn static_assert() {
${impl_simple_copy("contain", "mContain")}
${impl_simple_type_with_conversion("touch_action")}
pub fn set_offset_path(&mut self, v: longhands::offset_path::computed_value::T) {
use gecko_bindings::bindings::{Gecko_NewStyleMotion, Gecko_NewStyleSVGPath};
use gecko_bindings::bindings::Gecko_SetStyleMotion;
use gecko_bindings::structs::StyleShapeSourceType;
use values::specified::OffsetPath;
let motion = unsafe { Gecko_NewStyleMotion().as_mut().unwrap() };
match v {
OffsetPath::None => motion.mOffsetPath.mType = StyleShapeSourceType::None,
OffsetPath::Path(servo_path) => {
motion.mOffsetPath.mType = StyleShapeSourceType::Path;
let gecko_path = unsafe {
let ref mut source = motion.mOffsetPath;
Gecko_NewStyleSVGPath(source);
&mut source.__bindgen_anon_1.mSVGPath.as_mut().mPtr.as_mut().unwrap().mPath
};
unsafe { gecko_path.set_len(servo_path.commands().len() as u32) };
debug_assert_eq!(gecko_path.len(), servo_path.commands().len());
for (servo, gecko) in servo_path.commands().iter().zip(gecko_path.iter_mut()) {
// unsafe: cbindgen ensures the representation is the same.
*gecko = unsafe { transmute(*servo) };
}
},
}
unsafe { Gecko_SetStyleMotion(&mut self.gecko.mMotion, motion) };
}
pub fn clone_offset_path(&self) -> longhands::offset_path::computed_value::T {
use values::specified::OffsetPath;
match unsafe { self.gecko.mMotion.mPtr.as_ref() } {
None => OffsetPath::none(),
Some(v) => (&v.mOffsetPath).into()
}
}
pub fn copy_offset_path_from(&mut self, other: &Self) {
use gecko_bindings::bindings::Gecko_CopyStyleMotions;
unsafe { Gecko_CopyStyleMotions(&mut self.gecko.mMotion, other.gecko.mMotion.mPtr) };
}
pub fn reset_offset_path(&mut self, other: &Self) {
self.copy_offset_path_from(other);
}
</%self:impl_trait>
<%def name="simple_image_array_property(name, shorthand, field_name)">

View file

@ -356,6 +356,17 @@ ${helpers.predefined_type(
servo_restyle_damage="reflow_out_of_flow"
)}
// Motion Path Module Level 1
${helpers.predefined_type(
"offset-path",
"OffsetPath",
"computed::OffsetPath::none()",
animation_value_type="none",
gecko_pref="layout.css.motion-path.enabled",
flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
spec="https://drafts.fxtf.org/motion-1/#offset-path-property"
)}
// CSSOM View Module
// https://www.w3.org/TR/cssom-view-1/
${helpers.single_keyword("scroll-behavior",