Bug 1455358: Cleanup (a bit) system font copypasta. r?xidorn draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 19 Apr 2018 22:01:15 +0200
changeset 785222 db8179809dae9cbcfa80f145acac95bc59ed58c1
parent 785221 4c82661a9b5449543cb477042322d81b15bcae0d
push id107172
push userbmo:emilio@crisal.io
push dateThu, 19 Apr 2018 20:11:15 +0000
reviewersxidorn
bugs1455358
milestone61.0a1
Bug 1455358: Cleanup (a bit) system font copypasta. r?xidorn If I had to write that again I would've killed myself :). This is still not perfect, and the system font code is still quite a mess, but well, little steps. MozReview-Commit-ID: BmrZlCSejo7
servo/components/style/values/specified/font.rs
--- a/servo/components/style/values/specified/font.rs
+++ b/servo/components/style/values/specified/font.rs
@@ -21,16 +21,52 @@ use values::computed::{Angle as Computed
 use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue};
 use values::computed::font::{FamilyName, FontFamilyList, FontStyleAngle, SingleFontFamily};
 use values::generics::NonNegative;
 use values::generics::font::{self as generics, FeatureTagValue, FontSettings, FontTag};
 use values::generics::font::{KeywordInfo as GenericKeywordInfo, KeywordSize, VariationValue};
 use values::specified::{AllowQuirks, Angle, Integer, LengthOrPercentage, NoCalcLength, Number, Percentage};
 use values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX};
 
+// FIXME(emilio): The rest of the system font code is also copy-pasta, and
+// should be cleaned up.
+macro_rules! system_font_copy_pasta {
+    ($ty:ident, $field:ident) => {
+        system_font_copy_pasta!($ty);
+
+        fn compute_system(&self, _context: &Context) -> <$ty as ToComputedValue>::ComputedValue {
+            debug_assert!(matches!(*self, $ty::System(..)));
+            #[cfg(feature = "gecko")]
+            {
+                _context.cached_system_font.as_ref().unwrap().$field.clone()
+            }
+            #[cfg(feature = "servo")]
+            {
+                unreachable!()
+            }
+        }
+    };
+
+    ($ty:ident) => {
+        /// Get a specified value that represents a system font.
+        pub fn system_font(f: SystemFont) -> Self {
+            $ty::System(f)
+        }
+
+        /// Retreive a SystemFont from the specified value.
+        pub fn get_system(&self) -> Option<SystemFont> {
+            if let $ty::System(s) = *self {
+                Some(s)
+            } else {
+                None
+            }
+        }
+    }
+}
+
 const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8;
 const DEFAULT_SCRIPT_SIZE_MULTIPLIER: f64 = 0.71;
 
 /// The minimum font-weight value per:
 ///
 /// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values
 pub const MIN_FONT_WEIGHT: f32 = 1.;
 
@@ -50,42 +86,30 @@ pub enum FontWeight {
     Bolder,
     /// Lighter variant
     Lighter,
     /// System font variant.
     System(SystemFont),
 }
 
 impl FontWeight {
+    system_font_copy_pasta!(FontWeight, font_weight);
+
     /// `normal`
     #[inline]
     pub fn normal() -> Self {
         FontWeight::Absolute(AbsoluteFontWeight::Normal)
     }
 
     /// Get a specified FontWeight from a gecko keyword
     pub fn from_gecko_keyword(kw: u32) -> Self {
         debug_assert!(kw % 100 == 0);
         debug_assert!(kw as f32 <= MAX_FONT_WEIGHT);
         FontWeight::Absolute(AbsoluteFontWeight::Weight(Number::new(kw as f32)))
     }
-
-    /// Get a specified FontWeight from a SystemFont
-    pub fn system_font(f: SystemFont) -> Self {
-        FontWeight::System(f)
-    }
-
-    /// Retreive a SystemFont from FontWeight
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontWeight::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
 }
 
 impl Parse for FontWeight {
     fn parse<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<FontWeight, ParseError<'i>> {
         if let Ok(absolute) = input.try(|input| AbsoluteFontWeight::parse(context, input)) {
@@ -111,25 +135,17 @@ impl ToComputedValue for FontWeight {
                 .get_parent_font()
                 .clone_font_weight()
                 .bolder(),
             FontWeight::Lighter => context
                 .builder
                 .get_parent_font()
                 .clone_font_weight()
                 .lighter(),
-            #[cfg(feature = "gecko")]
-            FontWeight::System(_) => context
-                .cached_system_font
-                .as_ref()
-                .unwrap()
-                .font_weight
-                .clone(),
-            #[cfg(not(feature = "gecko"))]
-            FontWeight::System(_) => unreachable!(),
+            FontWeight::System(_) => self.compute_system(context),
         }
     }
 
     #[inline]
     fn from_computed_value(computed: &computed::FontWeight) -> Self {
         FontWeight::Absolute(AbsoluteFontWeight::Weight(
             Number::from_computed_value(&computed.0)
         ))
@@ -327,46 +343,26 @@ pub enum FontStyle {
 
 impl FontStyle {
     /// Return the `normal` value.
     #[inline]
     pub fn normal() -> Self {
         FontStyle::Specified(generics::FontStyle::Normal)
     }
 
-    /// More system font copy-pasta.
-    pub fn system_font(f: SystemFont) -> Self {
-        FontStyle::System(f)
-    }
-
-    /// Retreive a SystemFont from FontStyle.
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontStyle::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
+    system_font_copy_pasta!(FontStyle, font_style);
 }
 
 impl ToComputedValue for FontStyle {
     type ComputedValue = computed::FontStyle;
 
     fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
         match *self {
             FontStyle::Specified(ref specified) => specified.to_computed_value(context),
-            #[cfg(feature = "gecko")]
-            FontStyle::System(..) => context
-                .cached_system_font
-                .as_ref()
-                .unwrap()
-                .font_style
-                .clone(),
-            #[cfg(not(feature = "gecko"))]
-            FontStyle::System(_) => unreachable!(),
+            FontStyle::System(..) => self.compute_system(context),
         }
     }
 
     fn from_computed_value(computed: &Self::ComputedValue) -> Self {
         FontStyle::Specified(SpecifiedFontStyle::from_computed_value(computed))
     }
 }
 
@@ -426,31 +422,17 @@ impl FontStretchKeyword {
 }
 
 impl FontStretch {
     /// `normal`.
     pub fn normal() -> Self {
         FontStretch::Keyword(FontStretchKeyword::Normal)
     }
 
-    /// Get a specified FontStretch from a SystemFont.
-    ///
-    /// FIXME(emilio): All this system font stuff is copy-pasta. :(
-    pub fn system_font(f: SystemFont) -> Self {
-        FontStretch::System(f)
-    }
-
-    /// Retreive a SystemFont from FontStretch.
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontStretch::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
+    system_font_copy_pasta!(FontStretch, font_stretch);
 }
 
 impl Parse for FontStretch {
     fn parse<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         // From https://drafts.csswg.org/css-fonts-4/#font-stretch-prop:
@@ -472,25 +454,17 @@ impl ToComputedValue for FontStretch {
     fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
         match *self {
             FontStretch::Stretch(ref percentage) => {
                 NonNegative(percentage.to_computed_value(context))
             },
             FontStretch::Keyword(ref kw) => {
                 NonNegative(kw.compute())
             },
-            #[cfg(feature = "gecko")]
-            FontStretch::System(_) => context
-                .cached_system_font
-                .as_ref()
-                .unwrap()
-                .font_stretch
-                .clone(),
-            #[cfg(not(feature = "gecko"))]
-            FontStretch::System(_) => unreachable!(),
+            FontStretch::System(_) => self.compute_system(context),
         }
     }
 
     fn from_computed_value(computed: &Self::ComputedValue) -> Self {
         FontStretch::Stretch(Percentage::from_computed_value(&computed.0))
     }
 }
 
@@ -530,29 +504,17 @@ pub enum FontFamily {
     /// List of `font-family`
     #[css(comma)]
     Values(#[css(iterable)] FontFamilyList),
     /// System font
     System(SystemFont),
 }
 
 impl FontFamily {
-    /// Get `font-family` with system font
-    pub fn system_font(f: SystemFont) -> Self {
-        FontFamily::System(f)
-    }
-
-    /// Get system font
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontFamily::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
+    system_font_copy_pasta!(FontFamily, font_family);
 
     /// Parse a specified font-family value
     pub fn parse_specified<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         input
             .parse_comma_separated(|input| SingleFontFamily::parse(input))
             .map(|v| FontFamily::Values(FontFamilyList::new(v.into_boxed_slice())))
     }
 
@@ -564,29 +526,20 @@ impl FontFamily {
             _ => None,
         }
     }
 }
 
 impl ToComputedValue for FontFamily {
     type ComputedValue = computed::FontFamily;
 
-    fn to_computed_value(&self, _cx: &Context) -> Self::ComputedValue {
+    fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
         match *self {
             FontFamily::Values(ref v) => computed::FontFamily(v.clone()),
-            FontFamily::System(_) => {
-                #[cfg(feature = "gecko")]
-                {
-                    _cx.cached_system_font.as_ref().unwrap().font_family.clone()
-                }
-                #[cfg(feature = "servo")]
-                {
-                    unreachable!()
-                }
-            },
+            FontFamily::System(_) => self.compute_system(context),
         }
     }
 
     fn from_computed_value(other: &computed::FontFamily) -> Self {
         FontFamily::Values(other.0.clone())
     }
 }
 
@@ -646,54 +599,29 @@ pub enum FontSizeAdjust {
 
 impl FontSizeAdjust {
     #[inline]
     /// Default value of font-size-adjust
     pub fn none() -> Self {
         FontSizeAdjust::None
     }
 
-    /// Get font-size-adjust with SystemFont
-    pub fn system_font(f: SystemFont) -> Self {
-        FontSizeAdjust::System(f)
-    }
-
-    /// Get SystemFont variant
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontSizeAdjust::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
+    system_font_copy_pasta!(FontSizeAdjust, font_size_adjust);
 }
 
 impl ToComputedValue for FontSizeAdjust {
     type ComputedValue = computed::FontSizeAdjust;
 
     fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
         match *self {
             FontSizeAdjust::None => computed::FontSizeAdjust::None,
             FontSizeAdjust::Number(ref n) => {
                 computed::FontSizeAdjust::Number(n.to_computed_value(context))
             },
-            FontSizeAdjust::System(_) => {
-                #[cfg(feature = "gecko")]
-                {
-                    context
-                        .cached_system_font
-                        .as_ref()
-                        .unwrap()
-                        .font_size_adjust
-                }
-                #[cfg(feature = "servo")]
-                {
-                    unreachable!()
-                }
-            },
+            FontSizeAdjust::System(_) => self.compute_system(context),
         }
     }
 
     fn from_computed_value(computed: &computed::FontSizeAdjust) -> Self {
         match *computed {
             computed::FontSizeAdjust::None => FontSizeAdjust::None,
             computed::FontSizeAdjust::Number(ref v) => {
                 FontSizeAdjust::Number(Number::from_computed_value(v))
@@ -1007,32 +935,20 @@ impl ToComputedValue for FontSize {
     fn from_computed_value(computed: &computed::FontSize) -> Self {
         FontSize::Length(LengthOrPercentage::Length(
             ToComputedValue::from_computed_value(&computed.size.0),
         ))
     }
 }
 
 impl FontSize {
-    /// Construct a system font value.
-    pub fn system_font(f: SystemFont) -> Self {
-        FontSize::System(f)
-    }
+    system_font_copy_pasta!(FontSize);
 
-    /// Obtain the system font, if any
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontSize::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
-
+    /// Get initial value for specified font size.
     #[inline]
-    /// Get initial value for specified font size.
     pub fn medium() -> Self {
         FontSize::Keyword(KeywordInfo::medium())
     }
 
     /// Parses a font-size, with quirks.
     pub fn parse_quirky<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
@@ -1187,52 +1103,26 @@ pub enum FontVariantAlternates {
 
 impl FontVariantAlternates {
     #[inline]
     /// Get initial specified value with VariantAlternatesList
     pub fn get_initial_specified_value() -> Self {
         FontVariantAlternates::Value(VariantAlternatesList(vec![].into_boxed_slice()))
     }
 
-    /// Get FontVariantAlternates with system font
-    pub fn system_font(f: SystemFont) -> Self {
-        FontVariantAlternates::System(f)
-    }
-
-    /// Get SystemFont of FontVariantAlternates
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontVariantAlternates::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
+    system_font_copy_pasta!(FontVariantAlternates, font_variant_alternates);
 }
 
 impl ToComputedValue for FontVariantAlternates {
     type ComputedValue = computed::FontVariantAlternates;
 
-    fn to_computed_value(&self, _context: &Context) -> computed::FontVariantAlternates {
+    fn to_computed_value(&self, context: &Context) -> computed::FontVariantAlternates {
         match *self {
             FontVariantAlternates::Value(ref v) => v.clone(),
-            FontVariantAlternates::System(_) => {
-                #[cfg(feature = "gecko")]
-                {
-                    _context
-                        .cached_system_font
-                        .as_ref()
-                        .unwrap()
-                        .font_variant_alternates
-                        .clone()
-                }
-                #[cfg(feature = "servo")]
-                {
-                    unreachable!()
-                }
-            },
+            FontVariantAlternates::System(_) => self.compute_system(context),
         }
     }
 
     fn from_computed_value(other: &computed::FontVariantAlternates) -> Self {
         FontVariantAlternates::Value(other.clone())
     }
 }
 
@@ -1464,52 +1354,26 @@ pub enum FontVariantEastAsian {
 
 impl FontVariantEastAsian {
     #[inline]
     /// Get default `font-variant-east-asian` with `empty` variant
     pub fn empty() -> Self {
         FontVariantEastAsian::Value(VariantEastAsian::empty())
     }
 
-    /// Get `font-variant-east-asian` with system font
-    pub fn system_font(f: SystemFont) -> Self {
-        FontVariantEastAsian::System(f)
-    }
-
-    /// Get system font
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontVariantEastAsian::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
+    system_font_copy_pasta!(FontVariantEastAsian, font_variant_east_asian);
 }
 
 impl ToComputedValue for FontVariantEastAsian {
     type ComputedValue = computed::FontVariantEastAsian;
 
-    fn to_computed_value(&self, _context: &Context) -> computed::FontVariantEastAsian {
+    fn to_computed_value(&self, context: &Context) -> computed::FontVariantEastAsian {
         match *self {
             FontVariantEastAsian::Value(ref v) => v.clone(),
-            FontVariantEastAsian::System(_) => {
-                #[cfg(feature = "gecko")]
-                {
-                    _context
-                        .cached_system_font
-                        .as_ref()
-                        .unwrap()
-                        .font_variant_east_asian
-                        .clone()
-                }
-                #[cfg(feature = "servo")]
-                {
-                    unreachable!()
-                }
-            },
+            FontVariantEastAsian::System(_) => self.compute_system(context),
         }
     }
 
     fn from_computed_value(other: &computed::FontVariantEastAsian) -> Self {
         FontVariantEastAsian::Value(other.clone())
     }
 }
 
@@ -1710,64 +1574,38 @@ pub fn assert_variant_ligatures_matches(
 pub enum FontVariantLigatures {
     /// Value variant with `variant-ligatures`
     Value(VariantLigatures),
     /// System font variant
     System(SystemFont),
 }
 
 impl FontVariantLigatures {
-    /// Get `font-variant-ligatures` with system font
-    pub fn system_font(f: SystemFont) -> Self {
-        FontVariantLigatures::System(f)
-    }
+    system_font_copy_pasta!(FontVariantLigatures, font_variant_ligatures);
 
-    /// Get system font
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontVariantLigatures::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
-
+    /// Default value of `font-variant-ligatures` as `empty`
     #[inline]
-    /// Default value of `font-variant-ligatures` as `empty`
     pub fn empty() -> FontVariantLigatures {
         FontVariantLigatures::Value(VariantLigatures::empty())
     }
 
     #[inline]
     /// Get `none` variant of `font-variant-ligatures`
     pub fn none() -> FontVariantLigatures {
         FontVariantLigatures::Value(VariantLigatures::NONE)
     }
 }
 
 impl ToComputedValue for FontVariantLigatures {
     type ComputedValue = computed::FontVariantLigatures;
 
-    fn to_computed_value(&self, _context: &Context) -> computed::FontVariantLigatures {
+    fn to_computed_value(&self, context: &Context) -> computed::FontVariantLigatures {
         match *self {
             FontVariantLigatures::Value(ref v) => v.clone(),
-            FontVariantLigatures::System(_) => {
-                #[cfg(feature = "gecko")]
-                {
-                    _context
-                        .cached_system_font
-                        .as_ref()
-                        .unwrap()
-                        .font_variant_ligatures
-                        .clone()
-                }
-                #[cfg(feature = "servo")]
-                {
-                    unreachable!()
-                }
-            },
+            FontVariantLigatures::System(_) => self.compute_system(context),
         }
     }
 
     fn from_computed_value(other: &computed::FontVariantLigatures) -> Self {
         FontVariantLigatures::Value(other.clone())
     }
 }
 
@@ -1970,52 +1808,26 @@ pub enum FontVariantNumeric {
 
 impl FontVariantNumeric {
     #[inline]
     /// Default value of `font-variant-numeric` as `empty`
     pub fn empty() -> FontVariantNumeric {
         FontVariantNumeric::Value(VariantNumeric::empty())
     }
 
-    /// Get `font-variant-numeric` with system font
-    pub fn system_font(f: SystemFont) -> Self {
-        FontVariantNumeric::System(f)
-    }
-
-    /// Get system font
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontVariantNumeric::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
+    system_font_copy_pasta!(FontVariantNumeric, font_variant_numeric);
 }
 
 impl ToComputedValue for FontVariantNumeric {
     type ComputedValue = computed::FontVariantNumeric;
 
-    fn to_computed_value(&self, _context: &Context) -> computed::FontVariantNumeric {
+    fn to_computed_value(&self, context: &Context) -> computed::FontVariantNumeric {
         match *self {
             FontVariantNumeric::Value(ref v) => v.clone(),
-            FontVariantNumeric::System(_) => {
-                #[cfg(feature = "gecko")]
-                {
-                    _context
-                        .cached_system_font
-                        .as_ref()
-                        .unwrap()
-                        .font_variant_numeric
-                        .clone()
-                }
-                #[cfg(feature = "servo")]
-                {
-                    unreachable!()
-                }
-            },
+            FontVariantNumeric::System(_) => self.compute_system(context),
         }
     }
 
     fn from_computed_value(other: &computed::FontVariantNumeric) -> Self {
         FontVariantNumeric::Value(other.clone())
     }
 }
 
@@ -2103,52 +1915,26 @@ pub enum FontFeatureSettings {
 
 impl FontFeatureSettings {
     #[inline]
     /// Get default value of `font-feature-settings` as normal
     pub fn normal() -> FontFeatureSettings {
         FontFeatureSettings::Value(FontSettings::normal())
     }
 
-    /// Get `font-feature-settings` with system font
-    pub fn system_font(f: SystemFont) -> Self {
-        FontFeatureSettings::System(f)
-    }
-
-    /// Get system font
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontFeatureSettings::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
+    system_font_copy_pasta!(FontFeatureSettings, font_feature_settings);
 }
 
 impl ToComputedValue for FontFeatureSettings {
     type ComputedValue = computed::FontFeatureSettings;
 
     fn to_computed_value(&self, context: &Context) -> computed::FontFeatureSettings {
         match *self {
             FontFeatureSettings::Value(ref v) => v.to_computed_value(context),
-            FontFeatureSettings::System(_) => {
-                #[cfg(feature = "gecko")]
-                {
-                    context
-                        .cached_system_font
-                        .as_ref()
-                        .unwrap()
-                        .font_feature_settings
-                        .clone()
-                }
-                #[cfg(feature = "servo")]
-                {
-                    unreachable!()
-                }
-            },
+            FontFeatureSettings::System(_) => self.compute_system(context),
         }
     }
 
     fn from_computed_value(other: &computed::FontFeatureSettings) -> Self {
         FontFeatureSettings::Value(ToComputedValue::from_computed_value(other))
     }
 }
 
@@ -2278,63 +2064,38 @@ pub enum FontLanguageOverride {
 
 impl FontLanguageOverride {
     #[inline]
     /// Get default value with `normal`
     pub fn normal() -> FontLanguageOverride {
         FontLanguageOverride::Normal
     }
 
-    /// Get `font-language-override` with `system font`
-    pub fn system_font(f: SystemFont) -> Self {
-        FontLanguageOverride::System(f)
-    }
-
-    /// Get system font
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontLanguageOverride::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
+    system_font_copy_pasta!(FontLanguageOverride, font_language_override);
 }
 
 impl ToComputedValue for FontLanguageOverride {
     type ComputedValue = computed::FontLanguageOverride;
 
     #[inline]
-    fn to_computed_value(&self, _context: &Context) -> computed::FontLanguageOverride {
+    fn to_computed_value(&self, context: &Context) -> computed::FontLanguageOverride {
         match *self {
             FontLanguageOverride::Normal => computed::FontLanguageOverride(0),
             FontLanguageOverride::Override(ref lang) => {
                 if lang.is_empty() || lang.len() > 4 || !lang.is_ascii() {
                     return computed::FontLanguageOverride(0);
                 }
                 let mut computed_lang = lang.to_string();
                 while computed_lang.len() < 4 {
                     computed_lang.push(' ');
                 }
                 let bytes = computed_lang.into_bytes();
                 computed::FontLanguageOverride(BigEndian::read_u32(&bytes))
             },
-            FontLanguageOverride::System(_) => {
-                #[cfg(feature = "gecko")]
-                {
-                    _context
-                        .cached_system_font
-                        .as_ref()
-                        .unwrap()
-                        .font_language_override
-                }
-                #[cfg(feature = "servo")]
-                {
-                    unreachable!()
-                }
-            },
+            FontLanguageOverride::System(_) => self.compute_system(context),
         }
     }
     #[inline]
     fn from_computed_value(computed: &computed::FontLanguageOverride) -> Self {
         if computed.0 == 0 {
             return FontLanguageOverride::Normal;
         }
         let mut buf = [0; 4];
@@ -2385,52 +2146,26 @@ pub enum FontVariationSettings {
 
 impl FontVariationSettings {
     #[inline]
     /// Get default value of `font-variation-settings` as normal
     pub fn normal() -> FontVariationSettings {
         FontVariationSettings::Value(FontSettings::normal())
     }
 
-    /// Get `font-variation-settings` with system font
-    pub fn system_font(f: SystemFont) -> Self {
-        FontVariationSettings::System(f)
-    }
-
-    /// Get system font
-    pub fn get_system(&self) -> Option<SystemFont> {
-        if let FontVariationSettings::System(s) = *self {
-            Some(s)
-        } else {
-            None
-        }
-    }
+    system_font_copy_pasta!(FontVariationSettings, font_variation_settings);
 }
 
 impl ToComputedValue for FontVariationSettings {
     type ComputedValue = computed::FontVariationSettings;
 
     fn to_computed_value(&self, context: &Context) -> computed::FontVariationSettings {
         match *self {
             FontVariationSettings::Value(ref v) => v.to_computed_value(context),
-            FontVariationSettings::System(_) => {
-                #[cfg(feature = "gecko")]
-                {
-                    context
-                        .cached_system_font
-                        .as_ref()
-                        .unwrap()
-                        .font_variation_settings
-                        .clone()
-                }
-                #[cfg(feature = "servo")]
-                {
-                    unreachable!()
-                }
-            },
+            FontVariationSettings::System(_) => self.compute_system(context),
         }
     }
 
     fn from_computed_value(other: &computed::FontVariationSettings) -> Self {
         FontVariationSettings::Value(ToComputedValue::from_computed_value(other))
     }
 }