Bug 1349417 - Part 5: stylo: System font support for font-size-adjust; r?xidorn draft
authorManish Goregaokar <manishearth@gmail.com>
Tue, 21 Mar 2017 20:38:12 -0700
changeset 564173 acd8ac848e495b529bcb9f7c8855f4c79bd7f339
parent 564172 feb1cd187b7d8af415057ed36ac3971178a4c4bd
child 564174 b7412c05d863397487fb748cd2514658db925750
child 564498 35cb165374776e945ecbd08106931b0368296cd7
push id54548
push userbmo:manishearth@gmail.com
push dateTue, 18 Apr 2017 10:18:30 +0000
reviewersxidorn
bugs1349417
milestone55.0a1
Bug 1349417 - Part 5: stylo: System font support for font-size-adjust; r?xidorn MozReview-Commit-ID: 4q1zZUcw6zF
servo/components/style/properties/data.py
servo/components/style/properties/gecko.mako.rs
servo/components/style/properties/longhand/font.mako.rs
--- a/servo/components/style/properties/data.py
+++ b/servo/components/style/properties/data.py
@@ -10,17 +10,17 @@ PHYSICAL_SIZES = ["width", "height"]
 LOGICAL_SIZES = ["block-size", "inline-size"]
 
 # bool is True when logical
 ALL_SIDES = [(side, False) for side in PHYSICAL_SIDES] + [(side, True) for side in LOGICAL_SIDES]
 ALL_SIZES = [(size, False) for size in PHYSICAL_SIZES] + [(size, True) for size in LOGICAL_SIZES]
 
 SYSTEM_FONT_LONGHANDS = """font_family font_size font_style
                            font_variant_caps font_stretch font_kerning
-                           font_variant_position font_weight""".split()
+                           font_variant_position font_weight font_size_adjust""".split()
 
 def maybe_moz_logical_alias(product, side, prop):
     if product == "gecko" and side[1]:
         axis, dir = side[0].split("-")
         if axis == "inline":
             return prop % dir
     return None
 
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -1398,20 +1398,17 @@ fn static_assert() {
 
     pub fn copy_font_size_adjust_from(&mut self, other: &Self) {
         self.gecko.mFont.sizeAdjust = other.gecko.mFont.sizeAdjust;
     }
 
     pub fn clone_font_size_adjust(&self) -> longhands::font_size_adjust::computed_value::T {
         use properties::longhands::font_size_adjust::computed_value::T;
 
-        match self.gecko.mFont.sizeAdjust {
-            -1.0 => T::None,
-            _ => T::Number(self.gecko.mFont.sizeAdjust),
-        }
+        T::from_gecko_adjust(self.gecko.mFont.sizeAdjust)
     }
 
     #[allow(non_snake_case)]
     pub fn set__x_lang(&mut self, v: longhands::_x_lang::computed_value::T) {
         let ptr = v.0.as_ptr();
         forget(v);
         unsafe {
             Gecko_nsStyleFont_SetLang(&mut self.gecko, ptr);
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -816,58 +816,79 @@
                 None
             }
         }
     }
 </%helpers:longhand>
 
 <%helpers:longhand products="gecko" name="font-size-adjust" animation_type="normal"
                    spec="https://drafts.csswg.org/css-fonts/#propdef-font-size-adjust">
+    use properties::longhands::system_font::SystemFont;
     use std::fmt;
     use style_traits::ToCss;
     use values::HasViewportPercentage;
 
     no_viewport_percentage!(SpecifiedValue);
 
     #[derive(Copy, Clone, Debug, PartialEq)]
     #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         None,
         Number(specified::Number),
+        System(SystemFont),
     }
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result
             where W: fmt::Write,
         {
             match *self {
                 SpecifiedValue::None => dest.write_str("none"),
                 SpecifiedValue::Number(number) => number.to_css(dest),
+                SpecifiedValue::System(_) => Ok(()),
             }
         }
     }
 
     impl ToComputedValue for SpecifiedValue {
         type ComputedValue = computed_value::T;
 
         fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
             match *self {
                 SpecifiedValue::None => computed_value::T::None,
                 SpecifiedValue::Number(ref n) => computed_value::T::Number(n.to_computed_value(context)),
+                SpecifiedValue::System(_) => {
+                    <%self:nongecko_unreachable>
+                        context.style.cached_system_font.as_ref().unwrap().font_size_adjust
+                    </%self:nongecko_unreachable>
+                }
             }
         }
 
         fn from_computed_value(computed: &computed_value::T) -> Self {
             match *computed {
                 computed_value::T::None => SpecifiedValue::None,
                 computed_value::T::Number(ref v) => SpecifiedValue::Number(specified::Number::from_computed_value(v)),
             }
         }
     }
 
+    impl SpecifiedValue {
+        pub fn system_font(f: SystemFont) -> Self {
+            SpecifiedValue::System(f)
+        }
+        pub fn get_system(&self) -> Option<SystemFont> {
+            if let SpecifiedValue::System(s) = *self {
+                Some(s)
+            } else {
+                None
+            }
+        }
+    }
+
     pub mod computed_value {
         use properties::animated_properties::Interpolate;
         use std::fmt;
         use style_traits::ToCss;
         use values::CSSFloat;
 
         #[derive(Copy, Clone, Debug, PartialEq)]
         #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@@ -882,16 +903,25 @@
             {
                 match *self {
                     T::None => dest.write_str("none"),
                     T::Number(number) => number.to_css(dest),
                 }
             }
         }
 
+        impl T {
+            pub fn from_gecko_adjust(gecko: f32) -> Self {
+                match gecko {
+                    -1.0 => T::None,
+                    _ => T::Number(gecko),
+                }
+            }
+        }
+
         impl Interpolate for T {
             fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
                 match (*self, *other) {
                     (T::Number(ref number), T::Number(ref other)) =>
                         Ok(T::Number(try!(number.interpolate(other, time)))),
                     _ => Err(()),
                 }
             }
@@ -1916,32 +1946,51 @@ macro_rules! exclusive_value {
 </%helpers:longhand>
 
 
 % if product == "gecko":
     pub mod system_font {
         use app_units::Au;
         use cssparser::Parser;
         use properties::longhands;
+        use std::hash::{Hash, Hasher};
         use values::computed::{ToComputedValue, Context};
         <%
             system_fonts = """caption icon menu message-box small-caption status-bar
                               -moz-window -moz-document -moz-workspace -moz-desktop
                               -moz-info -moz-dialog -moz-button -moz-pull-down-menu
                               -moz-list -moz-field""".split()
             kw_font_props = """font_style font_variant_caps font_stretch
                                font_kerning font_variant_position""".split()
         %>
         #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
         pub enum SystemFont {
             % for font in system_fonts:
                 ${to_camel_case(font)},
             % endfor
         }
 
+        // ComputedValues are compared at times
+        // so we need these impls. We don't want to
+        // add Eq to Number (which contains a float)
+        // so instead we have an eq impl which skips the
+        // cached values
+        impl PartialEq for ComputedSystemFont {
+            fn eq(&self, other: &Self) -> bool {
+                self.system_font == other.system_font
+            }
+        }
+        impl Eq for ComputedSystemFont {}
+
+        impl Hash for ComputedSystemFont {
+            fn hash<H: Hasher>(&self, hasher: &mut H) {
+                self.system_font.hash(hasher)
+            }
+        }
+
         impl ToComputedValue for SystemFont {
             type ComputedValue = ComputedSystemFont;
 
             fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
                 use gecko_bindings::bindings;
                 use gecko_bindings::structs::{LookAndFeel_FontID, nsFont};
                 use std::mem;
 
@@ -1968,16 +2017,17 @@ macro_rules! exclusive_value {
                 }).collect::<Vec<_>>();
                 let weight = unsafe {
                     longhands::font_weight::computed_value::T::from_gecko_weight(system.weight)
                 };
                 let ret = ComputedSystemFont {
                     font_family: longhands::font_family::computed_value::T(family),
                     font_size: Au(system.size),
                     font_weight: weight,
+                    font_size_adjust: longhands::font_size_adjust::computed_value::T::from_gecko_adjust(system.sizeAdjust),
                     % for kwprop in kw_font_props:
                         ${kwprop}: longhands::${kwprop}::computed_value::T::from_gecko_keyword(
                             system.${to_camel_case_lower(kwprop.replace('font_', ''))} as u32
                         ),
                     % endfor
                     system_font: *self,
                 };
                 unsafe { bindings::Gecko_nsFont_Destroy(&mut system); }
@@ -1997,17 +2047,17 @@ macro_rules! exclusive_value {
         pub fn resolve_system_font(system: SystemFont, context: &mut Context) {
             if context.style.cached_system_font.is_none() {
                 let computed = system.to_computed_value(context);
                 context.style.cached_system_font = Some(computed);
             }
             debug_assert!(system == context.style.cached_system_font.as_ref().unwrap().system_font)
         }
 
-        #[derive(Clone, Debug, PartialEq, Eq, Hash)]
+        #[derive(Clone, Debug)]
         pub struct ComputedSystemFont {
             % for name in SYSTEM_FONT_LONGHANDS:
                 pub ${name}: longhands::${name}::computed_value::T,
             % endfor
             pub system_font: SystemFont,
         }
 
         impl SystemFont {