servo: Merge #11445 - Support line-height in geckolib (from mbrubeck:line-height); r=emilio
authorMatt Brubeck <mbrubeck@limpet.net>
Wed, 01 Jun 2016 05:58:56 -0500
changeset 338973 ce3b753ff7eb73e78ad6077d77beda3b4d9e48e1
parent 338972 b867b288a8fbd4e03b3ba1c60d6ffb33afb5cd6b
child 338974 97bab307c0ad6fab34b6c4b91efed7ec439c256a
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
servo: Merge #11445 - Support line-height in geckolib (from mbrubeck:line-height); r=emilio r? @bholley Source-Repo: https://github.com/servo/servo Source-Revision: 8caa17a466025adf9e6635e140951c014b33c5d8
servo/components/style/properties/longhand/inherited_text.mako.rs
servo/ports/geckolib/properties.mako.rs
servo/ports/geckolib/values.rs
servo/ports/geckolib/wrapper.rs
--- a/servo/components/style/properties/longhand/inherited_text.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_text.mako.rs
@@ -10,24 +10,30 @@
     use cssparser::ToCss;
     use std::fmt;
     use values::AuExtensionMethods;
     use values::CSSFloat;
 
     #[derive(Debug, Clone, PartialEq, Copy, HeapSizeOf)]
     pub enum SpecifiedValue {
         Normal,
+        % if product == "gecko":
+            MozBlockHeight,
+        % endif
         Number(CSSFloat),
         LengthOrPercentage(specified::LengthOrPercentage),
     }
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match *self {
                 SpecifiedValue::Normal => dest.write_str("normal"),
+                % if product == "gecko":
+                    SpecifiedValue::MozBlockHeight => dest.write_str("-moz-block-height"),
+                % endif
                 SpecifiedValue::LengthOrPercentage(value) => value.to_css(dest),
                 SpecifiedValue::Number(number) => write!(dest, "{}", number),
             }
         }
     }
     /// normal | <number> | <length> | <percentage>
     pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
         use cssparser::Token;
@@ -37,50 +43,64 @@
         .or_else(|()| {
             match try!(input.next()) {
                 Token::Number(ref value) if value.value >= 0. => {
                     Ok(SpecifiedValue::Number(value.value))
                 }
                 Token::Ident(ref value) if value.eq_ignore_ascii_case("normal") => {
                     Ok(SpecifiedValue::Normal)
                 }
+                % if product == "gecko":
+                Token::Ident(ref value) if value.eq_ignore_ascii_case("-moz-block-height") => {
+                    Ok(SpecifiedValue::MozBlockHeight)
+                }
+                % endif
                 _ => Err(()),
             }
         })
     }
     pub mod computed_value {
         use app_units::Au;
         use std::fmt;
         use values::CSSFloat;
         #[derive(PartialEq, Copy, Clone, HeapSizeOf, Debug)]
         pub enum T {
             Normal,
+            % if product == "gecko":
+                MozBlockHeight,
+            % endif
             Length(Au),
             Number(CSSFloat),
         }
     }
     impl ToCss for computed_value::T {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match *self {
                 computed_value::T::Normal => dest.write_str("normal"),
+                % if product == "gecko":
+                    computed_value::T::MozBlockHeight => dest.write_str("-moz-block-height"),
+                % endif
                 computed_value::T::Length(length) => length.to_css(dest),
                 computed_value::T::Number(number) => write!(dest, "{}", number),
             }
         }
     }
      #[inline]
     pub fn get_initial_value() -> computed_value::T { computed_value::T::Normal }
 
     impl ToComputedValue for SpecifiedValue {
         type ComputedValue = computed_value::T;
 
         #[inline]
         fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
             match *self {
                 SpecifiedValue::Normal => computed_value::T::Normal,
+                % if product == "gecko":
+                    SpecifiedValue::MozBlockHeight => computed_value::T::MozBlockHeight,
+                % endif
                 SpecifiedValue::Number(value) => computed_value::T::Number(value),
                 SpecifiedValue::LengthOrPercentage(value) => {
                     match value {
                         specified::LengthOrPercentage::Length(value) =>
                             computed_value::T::Length(value.to_computed_value(context)),
                         specified::LengthOrPercentage::Percentage(specified::Percentage(value)) => {
                             let fr = specified::Length::FontRelative(specified::FontRelativeLength::Em(value));
                             computed_value::T::Length(fr.to_computed_value(context))
--- a/servo/ports/geckolib/properties.mako.rs
+++ b/servo/ports/geckolib/properties.mako.rs
@@ -15,17 +15,16 @@ use gecko_bindings::structs::${style_str
 use gecko_bindings::bindings::Gecko_Construct_${style_struct.gecko_ffi_name};
 use gecko_bindings::bindings::Gecko_CopyConstruct_${style_struct.gecko_ffi_name};
 use gecko_bindings::bindings::Gecko_Destroy_${style_struct.gecko_ffi_name};
 % endfor
 use gecko_bindings::bindings::{Gecko_CopyMozBindingFrom, Gecko_CopyListStyleTypeFrom};
 use gecko_bindings::bindings::{Gecko_SetMozBinding, Gecko_SetListStyleType};
 use gecko_bindings::structs;
 use glue::ArcHelpers;
-use heapsize::HeapSizeOf;
 use std::fmt::{self, Debug};
 use std::mem::{transmute, zeroed};
 use std::sync::Arc;
 use style::custom_properties::ComputedValuesMap;
 use style::logical_geometry::WritingMode;
 use style::properties::{CascadePropertyFn, ServoComputedValues, ComputedValues};
 use style::properties::longhands;
 use style::properties::make_cascade_vec;
@@ -144,16 +143,22 @@ pub struct ${style_struct.gecko_struct_n
 </%def>
 
 <%def name="impl_simple_copy(ident, gecko_ffi_name)">
     fn copy_${ident}_from(&mut self, other: &Self) {
         self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name};
     }
 </%def>
 
+<%def name="impl_coord_copy(ident, gecko_ffi_name)">
+    fn copy_${ident}_from(&mut self, other: &Self) {
+        self.gecko.${gecko_ffi_name}.copy_from(&other.gecko.${gecko_ffi_name});
+    }
+</%def>
+
 <%!
 def is_border_style_masked(ffi_name):
     return ffi_name.split("[")[0] in ["mBorderStyle", "mOutlineStyle", "mTextDecorationStyle"]
 
 def get_gecko_property(ffi_name):
     if is_border_style_masked(ffi_name):
         return "(self.gecko.%s & (structs::BORDER_STYLE_MASK as u8))" % ffi_name
     return "self.gecko.%s" % ffi_name
@@ -668,21 +673,18 @@ fn static_assert() {
         match v {
             % for value in keyword.values_for('gecko'):
                 T::${to_rust_ident(value)} =>
                     self.gecko.mVerticalAlign.set_enum(structs::${keyword.gecko_constant(value)} as i32),
             % endfor
             T::LengthOrPercentage(v) => self.gecko.mVerticalAlign.set(v),
         }
     }
-    fn copy_vertical_align_from(&mut self, other: &Self) {
-        debug_assert_unit_is_safe_to_copy(self.gecko.mVerticalAlign.mUnit);
-        self.gecko.mVerticalAlign.mUnit = other.gecko.mVerticalAlign.mUnit;
-        self.gecko.mVerticalAlign.mValue = other.gecko.mVerticalAlign.mValue;
-    }
+
+    <%call expr="impl_coord_copy('vertical_align', 'mVerticalAlign')"></%call>
 
     fn set__moz_binding(&mut self, v: longhands::_moz_binding::computed_value::T) {
         use style::properties::longhands::_moz_binding::SpecifiedValue as BindingValue;
         match v {
             BindingValue::None => debug_assert!(self.gecko.mBinding.mRawPtr.is_null()),
             BindingValue::Url(ref url, ref extra_data) => {
                 unsafe {
                     Gecko_SetMozBinding(&mut self.gecko,
@@ -714,22 +716,36 @@ fn static_assert() {
         unsafe {
             Gecko_CopyListStyleTypeFrom(&mut self.gecko, &other.gecko);
         }
     }
 
 </%self:impl_trait>
 
 <%self:impl_trait style_struct_name="InheritedText"
-                  skip_longhands="text-align">
+                  skip_longhands="text-align line-height">
 
     <% text_align_keyword = Keyword("text-align", "start end left right center justify -moz-center -moz-left " +
                                                   "-moz-right match-parent") %>
     <%call expr="impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)"></%call>
 
+    fn set_line_height(&mut self, v: longhands::line_height::computed_value::T) {
+        use style::properties::longhands::line_height::computed_value::T;
+        // FIXME: Align binary representations and ditch |match| for cast + static_asserts
+        match v {
+            T::Normal => self.gecko.mLineHeight.set_normal(),
+            T::Length(val) => self.gecko.mLineHeight.set_coord(val),
+            T::Number(val) => self.gecko.mLineHeight.set_factor(val),
+            T::MozBlockHeight =>
+                self.gecko.mLineHeight.set_enum(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT as i32),
+        }
+    }
+
+    <%call expr="impl_coord_copy('line_height', 'mLineHeight')"></%call>
+
 </%self:impl_trait>
 
 <%self:impl_trait style_struct_name="Text"
                   skip_longhands="text-decoration-color text-decoration-line"
                   skip_additionals="*">
 
     <% impl_color("text_decoration_color", "mTextDecorationColor",
                   color_flags_ffi_name="mTextDecorationStyle") %>
--- a/servo/ports/geckolib/values.rs
+++ b/servo/ports/geckolib/values.rs
@@ -4,34 +4,49 @@
 
 use app_units::Au;
 use cssparser::RGBA;
 use gecko_bindings::structs::{nsStyleCoord, nsStyleUnion, nsStyleUnit};
 use std::cmp::max;
 use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
 
 pub trait StyleCoordHelpers {
+    fn copy_from(&mut self, other: &Self);
     fn set<T: ToGeckoStyleCoord>(&mut self, val: T);
     fn set_auto(&mut self);
+    fn set_normal(&mut self);
     fn set_coord(&mut self, val: Au);
     fn set_int(&mut self, val: i32);
     fn set_enum(&mut self, val: i32);
     fn set_percent(&mut self, val: f32);
+    fn set_factor(&mut self, val: f32);
 }
 
 impl StyleCoordHelpers for nsStyleCoord {
+    fn copy_from(&mut self, other: &Self) {
+        debug_assert_unit_is_safe_to_copy(self.mUnit);
+        debug_assert_unit_is_safe_to_copy(other.mUnit);
+        self.mUnit = other.mUnit;
+        self.mValue = other.mValue;
+    }
+
     fn set<T: ToGeckoStyleCoord>(&mut self, val: T) {
         val.to_gecko_style_coord(&mut self.mUnit, &mut self.mValue);
     }
 
     fn set_auto(&mut self) {
         self.mUnit = nsStyleUnit::eStyleUnit_Auto;
         unsafe { *self.mValue.mInt.as_mut() = 0; }
     }
 
+    fn set_normal(&mut self) {
+        self.mUnit = nsStyleUnit::eStyleUnit_Normal;
+        unsafe { *self.mValue.mInt.as_mut() = 0; }
+    }
+
     fn set_coord(&mut self, val: Au) {
         self.mUnit = nsStyleUnit::eStyleUnit_Coord;
         unsafe { *self.mValue.mInt.as_mut() = val.0; }
     }
 
     fn set_percent(&mut self, val: f32) {
         self.mUnit = nsStyleUnit::eStyleUnit_Percent;
         unsafe { *self.mValue.mFloat.as_mut() = val; }
@@ -41,16 +56,21 @@ impl StyleCoordHelpers for nsStyleCoord 
         self.mUnit = nsStyleUnit::eStyleUnit_Integer;
         unsafe { *self.mValue.mInt.as_mut() = val; }
     }
 
     fn set_enum(&mut self, val: i32) {
         self.mUnit = nsStyleUnit::eStyleUnit_Enumerated;
         unsafe { *self.mValue.mInt.as_mut() = val; }
     }
+
+    fn set_factor(&mut self, val: f32) {
+        self.mUnit = nsStyleUnit::eStyleUnit_Factor;
+        unsafe { *self.mValue.mFloat.as_mut() = val; }
+    }
 }
 
 pub trait ToGeckoStyleCoord {
     fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion);
 }
 
 impl ToGeckoStyleCoord for LengthOrPercentage {
     fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
--- a/servo/ports/geckolib/wrapper.rs
+++ b/servo/ports/geckolib/wrapper.rs
@@ -36,16 +36,17 @@ use std::slice;
 use std::str::from_utf8_unchecked;
 use std::sync::Arc;
 use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
 use style::dom::{OpaqueNode, PresentationalHintsSynthetizer};
 use style::dom::{TDocument, TElement, TNode, TRestyleDamage, UnsafeNode};
 use style::element_state::ElementState;
 #[allow(unused_imports)] // Used in commented-out code.
 use style::error_reporting::StdoutErrorReporter;
+#[allow(unused_imports)] // Used in commented-out code.
 use style::parser::ParserContextExtraData;
 #[allow(unused_imports)] // Used in commented-out code.
 use style::properties::parse_style_attribute;
 use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
 use style::restyle_hints::ElementSnapshot;
 use style::selector_impl::ElementExt;
 #[allow(unused_imports)] // Used in commented-out code.
 use url::Url;