Bug 1371115 - Part 14: implements StyleShapeSource type properties animatable. r?hiro draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Fri, 23 Jun 2017 15:27:40 +0900
changeset 599462 8a8bfadf2c242e9ec26d0069d03265b6fd09048d
parent 599461 c0941741eea64f2ba14545138d955bd36746d849
child 599463 6ad185037b7f199f30f84e479ae67054636a0879
push id65535
push userbmo:dakatsuka@mozilla.com
push dateFri, 23 Jun 2017 06:52:43 +0000
reviewershiro
bugs1371115
milestone56.0a1
Bug 1371115 - Part 14: implements StyleShapeSource type properties animatable. r?hiro In this patch, implements following properties: * shape-outside MozReview-Commit-ID: DbzxBqaR6Xs
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
servo/components/style/gecko/conversions.rs
servo/components/style/properties/gecko.mako.rs
servo/components/style/properties/longhand/box.mako.rs
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -1840,16 +1840,28 @@ Gecko_DestroyShapeSource(mozilla::StyleS
 
 void
 Gecko_StyleShapeSource_SetURLValue(mozilla::StyleShapeSource* aShape, ServoBundledURI aURI)
 {
   RefPtr<css::URLValue> url = aURI.IntoCssUrl();
   aShape->SetURL(url.get());
 }
 
+const mozilla::css::URLValueData*
+Gecko_StyleShapeSource_GetURLValue(const mozilla::StyleShapeSource* aShape)
+{
+  return aShape->GetURL();
+}
+
+const mozilla::StyleBasicShape*
+Gecko_StyleShapeSource_GetBasicShape(const mozilla::StyleShapeSource* aShape)
+{
+  return aShape->GetBasicShape();
+}
+
 mozilla::StyleBasicShape*
 Gecko_NewBasicShape(mozilla::StyleBasicShapeType aType)
 {
   RefPtr<StyleBasicShape> ptr = new mozilla::StyleBasicShape(aType);
   return ptr.forget().take();
 }
 
 void
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -458,16 +458,18 @@ void Gecko_ResetStyleCoord(nsStyleUnit* 
 // Set an nsStyleCoord to a computed `calc()` value
 void Gecko_SetStyleCoordCalcValue(nsStyleUnit* unit, nsStyleUnion* value, nsStyleCoord::CalcValue calc);
 
 void Gecko_CopyShapeSourceFrom(mozilla::StyleShapeSource* dst, const mozilla::StyleShapeSource* src);
 
 void Gecko_DestroyShapeSource(mozilla::StyleShapeSource* shape);
 mozilla::StyleBasicShape* Gecko_NewBasicShape(mozilla::StyleBasicShapeType type);
 void Gecko_StyleShapeSource_SetURLValue(mozilla::StyleShapeSource* shape, ServoBundledURI uri);
+const mozilla::css::URLValueData* Gecko_StyleShapeSource_GetURLValue(const mozilla::StyleShapeSource* shape);
+const mozilla::StyleBasicShape* Gecko_StyleShapeSource_GetBasicShape(const mozilla::StyleShapeSource* shape);
 
 void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len);
 void Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest);
 void Gecko_nsStyleFilter_SetURLValue(nsStyleFilter* effects, ServoBundledURI uri);
 
 void Gecko_nsStyleSVGPaint_CopyFrom(nsStyleSVGPaint* dest, const nsStyleSVGPaint* src);
 void Gecko_nsStyleSVGPaint_SetURLValue(nsStyleSVGPaint* paint, ServoBundledURI uri);
 void Gecko_nsStyleSVGPaint_Reset(nsStyleSVGPaint* paint);
--- a/servo/components/style/gecko/conversions.rs
+++ b/servo/components/style/gecko/conversions.rs
@@ -710,16 +710,29 @@ pub mod basic_shape {
                 MarginBox => GeometryBox::ShapeBox(ShapeBox::MarginBox),
                 FillBox => GeometryBox::FillBox,
                 StrokeBox => GeometryBox::StrokeBox,
                 ViewBox => GeometryBox::ViewBox,
                 other => panic!("Unexpected StyleGeometryBox::{:?} while converting to GeometryBox", other),
             }
         }
     }
+
+    impl From<StyleGeometryBox> for ShapeBox {
+        fn from(reference: StyleGeometryBox) -> Self {
+            use gecko_bindings::structs::StyleGeometryBox::*;
+            match reference {
+                ContentBox => ShapeBox::ContentBox,
+                PaddingBox => ShapeBox::PaddingBox,
+                BorderBox => ShapeBox::BorderBox,
+                MarginBox => ShapeBox::MarginBox,
+                other => panic!("Unexpected StyleGeometryBox::{:?} while converting to ShapeBox", other),
+            }
+        }
+    }
 }
 
 impl From<RulesMutateError> for nsresult {
     fn from(other: RulesMutateError) -> Self {
         match other {
             RulesMutateError::Syntax => nsresult::NS_ERROR_DOM_SYNTAX_ERR,
             RulesMutateError::IndexSize => nsresult::NS_ERROR_DOM_INDEX_SIZE_ERR,
             RulesMutateError::HierarchyRequest => nsresult::NS_ERROR_DOM_HIERARCHY_REQUEST_ERR,
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -2822,17 +2822,17 @@ fn static_assert() {
                             unsafe { Atom::from_addrefed(*gecko_atom as *mut nsIAtom) }
                         )
                     }).collect()
                 )
             }
         }
     }
 
-    <% impl_shape_source("shape_outside", "mShapeOutside") %>
+    <% impl_shape_source("shape_outside", "mShapeOutside", "ShapeBox") %>
 
     pub fn set_contain(&mut self, v: longhands::contain::computed_value::T) {
         use gecko_bindings::structs::NS_STYLE_CONTAIN_NONE;
         use gecko_bindings::structs::NS_STYLE_CONTAIN_STRICT;
         use gecko_bindings::structs::NS_STYLE_CONTAIN_LAYOUT;
         use gecko_bindings::structs::NS_STYLE_CONTAIN_STYLE;
         use gecko_bindings::structs::NS_STYLE_CONTAIN_PAINT;
         use gecko_bindings::structs::NS_STYLE_CONTAIN_ALL_BITS;
@@ -4110,17 +4110,17 @@ fn static_assert() {
     }
 
     #[inline]
     pub fn has_line_through(&self) -> bool {
         (self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH as u8)) != 0
     }
 </%self:impl_trait>
 
-<%def name="impl_shape_source(ident, gecko_ffi_name)">
+<%def name="impl_shape_source(ident, gecko_ffi_name, box_type)">
     pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
         use gecko_bindings::bindings::{Gecko_NewBasicShape, Gecko_DestroyShapeSource};
         use gecko_bindings::structs::{StyleBasicShape, StyleBasicShapeType, StyleShapeSourceType};
         use gecko_bindings::structs::{StyleFillRule, StyleGeometryBox, StyleShapeSource};
         use gecko::conversions::basic_shape::set_corners_from_radius;
         use gecko::values::GeckoStyleCoordConvertible;
         use values::generics::basic_shape::{BasicShape, FillRule, ShapeSource};
         let ref mut ${ident} = self.gecko.${gecko_ffi_name};
@@ -4219,31 +4219,65 @@ fn static_assert() {
     }
 
     pub fn copy_${ident}_from(&mut self, other: &Self) {
         use gecko_bindings::bindings::Gecko_CopyShapeSourceFrom;
         unsafe {
             Gecko_CopyShapeSourceFrom(&mut self.gecko.${gecko_ffi_name}, &other.gecko.${gecko_ffi_name});
         }
     }
+
+    pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
+        use gecko_bindings::bindings::{Gecko_StyleShapeSource_GetURLValue, Gecko_StyleShapeSource_GetBasicShape};
+        use gecko_bindings::structs::{StyleShapeSourceType, StyleGeometryBox};
+        use values::generics::basic_shape::{BasicShape, ${box_type}, ShapeSource};
+        use values::specified::url::SpecifiedUrl;
+
+        let ref gecko_value = self.gecko.${gecko_ffi_name};
+        match gecko_value.mType {
+            StyleShapeSourceType::None => ShapeSource::None,
+            StyleShapeSourceType::URL => {
+                unsafe {
+                    let gecko_url = Gecko_StyleShapeSource_GetURLValue(gecko_value);
+                    debug_assert!(!gecko_url.is_null());
+                    ShapeSource::Url(SpecifiedUrl::from_url_value_data(gecko_url.as_ref().unwrap())
+                                     .expect("${ident} has valid URL data"))
+                }
+            },
+            StyleShapeSourceType::Box => {
+                ShapeSource::Box(${box_type}::from(gecko_value.mReferenceBox))
+            },
+            StyleShapeSourceType::Shape => {
+                let box_option = match gecko_value.mReferenceBox {
+                    StyleGeometryBox::NoBox => None,
+                    _ => Some(${box_type}::from(gecko_value.mReferenceBox))
+                };
+                unsafe {
+                    let gecko_shape = Gecko_StyleShapeSource_GetBasicShape(gecko_value);
+                    debug_assert!(!gecko_shape.is_null());
+                    ShapeSource::Shape(BasicShape::from(gecko_shape.as_ref().unwrap()), box_option)
+                }
+            }
+        }
+    }
 </%def>
 
 <% skip_svg_longhands = """
 mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask-position-y mask-size mask-image
 clip-path
 """
 %>
 <%self:impl_trait style_struct_name="SVG"
                   skip_longhands="${skip_svg_longhands}"
                   skip_additionals="*">
 
     <% impl_common_image_layer_properties("mask") %>
     <% impl_simple_image_array_property("mode", "mask", "mMask", "mMaskMode", "SVG") %>
     <% impl_simple_image_array_property("composite", "mask", "mMask", "mComposite", "SVG") %>
-    <% impl_shape_source("clip_path", "mClipPath") %>
+    <% impl_shape_source("clip_path", "mClipPath", "GeometryBox") %>
 </%self:impl_trait>
 
 <%self:impl_trait style_struct_name="InheritedSVG"
                   skip_longhands="paint-order stroke-dasharray stroke-dashoffset stroke-width -moz-context-properties"
                   skip_additionals="*">
     pub fn set_paint_order(&mut self, v: longhands::paint_order::computed_value::T) {
         use self::longhands::paint_order;
 
--- a/servo/components/style/properties/longhand/box.mako.rs
+++ b/servo/components/style/properties/longhand/box.mako.rs
@@ -1923,17 +1923,17 @@
             }).map(SpecifiedValue::AnimateableFeatures)
         }
     }
 </%helpers:longhand>
 
 ${helpers.predefined_type("shape-outside", "basic_shape::FloatAreaShape",
                           "generics::basic_shape::ShapeSource::None",
                           products="gecko", boxed="True",
-                          animation_value_type="none",
+                          animation_value_type="discrete",
                           spec="https://drafts.csswg.org/css-shapes/#shape-outside-property")}
 
 <%helpers:longhand name="touch-action"
                    products="gecko"
                    animation_value_type="discrete"
                    disable_when_testing="True"
                    spec="https://compat.spec.whatwg.org/#touch-action">
     use gecko_bindings::structs;