Bug 1434130 part 4 - Use unified lists to impl several bitflag font-variant properties. r=emilio
authorXidorn Quan <me@upsuper.org>
Sun, 29 Apr 2018 09:03:31 +1000
changeset 469755 543c9e49bfe5df7547448a28ebc663ef1620f406
parent 469754 cebd5132edfc1f48cba9ebb4561925ed4c710876
child 469756 10da0873e0a5874fcd64100a3ce3dc9a49b59452
push id9174
push userarchaeopteryx@coole-files.de
push dateMon, 30 Apr 2018 15:33:30 +0000
treeherdermozilla-beta@1b1a8ab75f1f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1434130
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1434130 part 4 - Use unified lists to impl several bitflag font-variant properties. r=emilio This also changes their ToCss impl to use SequenceWriter instead of checking has_value manually. SpecifiedValueInfo for those types are also implemented in this patch. MozReview-Commit-ID: 23h2VWS417H
servo/components/style/values/specified/font.rs
--- a/servo/components/style/values/specified/font.rs
+++ b/servo/components/style/values/specified/font.rs
@@ -10,17 +10,19 @@ use byteorder::{BigEndian, ByteOrder};
 use cssparser::{Parser, Token};
 #[cfg(feature = "gecko")]
 use gecko_bindings::bindings;
 #[cfg(feature = "gecko")]
 use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
 use parser::{Parse, ParserContext};
 use properties::longhands::system_font::SystemFont;
 use std::fmt::{self, Write};
-use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss};
+use style_traits::{CssWriter, KeywordsCollectFn, ParseError};
+use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
+use style_traits::values::SequenceWriter;
 use values::CustomIdent;
 use values::computed::{Angle as ComputedAngle, Percentage as ComputedPercentage};
 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};
@@ -1270,130 +1272,112 @@ impl Parse for FontVariantAlternates {
             return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
         }
         Ok(FontVariantAlternates::Value(VariantAlternatesList(
             alternates.into_boxed_slice(),
         )))
     }
 }
 
-bitflags! {
-    #[derive(MallocSizeOf)]
-    /// Vairants for east asian variant
-    pub struct VariantEastAsian: u16 {
-        /// None of the features
-        const NORMAL = 0;
-        /// Enables rendering of JIS78 forms (OpenType feature: jp78)
-        const JIS78 = 0x01;
-        /// Enables rendering of JIS83 forms (OpenType feature: jp83).
-        const JIS83 = 0x02;
-        /// Enables rendering of JIS90 forms (OpenType feature: jp90).
-        const JIS90 = 0x04;
-        /// Enables rendering of JIS2004 forms (OpenType feature: jp04).
-        const JIS04 = 0x08;
-        /// Enables rendering of simplified forms (OpenType feature: smpl).
-        const SIMPLIFIED = 0x10;
-        /// Enables rendering of traditional forms (OpenType feature: trad).
-        const TRADITIONAL = 0x20;
-        /// Enables rendering of full-width variants (OpenType feature: fwid).
-        const FULL_WIDTH = 0x40;
-        /// Enables rendering of proportionally-spaced variants (OpenType feature: pwid).
-        const PROPORTIONAL_WIDTH = 0x80;
-        /// Enables display of ruby variant glyphs (OpenType feature: ruby).
-        const RUBY = 0x100;
+macro_rules! impl_variant_east_asian {
+    {
+        $(
+            $(#[$($meta:tt)+])*
+            $ident:ident / $css:expr => $gecko:ident = $value:expr,
+        )+
+    } => {
+        bitflags! {
+            #[derive(MallocSizeOf)]
+            /// Vairants for east asian variant
+            pub struct VariantEastAsian: u16 {
+                /// None of the features
+                const NORMAL = 0;
+                $(
+                    $(#[$($meta)+])*
+                    const $ident = $value;
+                )+
+            }
+        }
+
+        impl ToCss for VariantEastAsian {
+            fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
+            where
+                W: Write,
+            {
+                if self.is_empty() {
+                    return dest.write_str("normal");
+                }
+
+                let mut writer = SequenceWriter::new(dest, " ");
+                $(
+                    if self.intersects(VariantEastAsian::$ident) {
+                        writer.raw_item($css)?;
+                    }
+                )+
+                Ok(())
+            }
+        }
+
+        /// Asserts that all variant-east-asian matches its NS_FONT_VARIANT_EAST_ASIAN_* value.
+        #[cfg(feature = "gecko")]
+        #[inline]
+        pub fn assert_variant_east_asian_matches() {
+            use gecko_bindings::structs;
+            $(
+                debug_assert_eq!(structs::$gecko as u16, VariantEastAsian::$ident.bits());
+            )+
+        }
+
+        impl SpecifiedValueInfo for VariantEastAsian {
+            fn collect_completion_keywords(f: KeywordsCollectFn) {
+                f(&["normal", $($css,)+]);
+            }
+        }
     }
 }
 
+impl_variant_east_asian! {
+    /// Enables rendering of JIS78 forms (OpenType feature: jp78)
+    JIS78 / "jis78" => NS_FONT_VARIANT_EAST_ASIAN_JIS78 = 0x01,
+    /// Enables rendering of JIS83 forms (OpenType feature: jp83).
+    JIS83 / "jis83" => NS_FONT_VARIANT_EAST_ASIAN_JIS83 = 0x02,
+    /// Enables rendering of JIS90 forms (OpenType feature: jp90).
+    JIS90 / "jis90" => NS_FONT_VARIANT_EAST_ASIAN_JIS90 = 0x04,
+    /// Enables rendering of JIS2004 forms (OpenType feature: jp04).
+    JIS04 / "jis04" => NS_FONT_VARIANT_EAST_ASIAN_JIS04 = 0x08,
+    /// Enables rendering of simplified forms (OpenType feature: smpl).
+    SIMPLIFIED / "simplified" => NS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED = 0x10,
+    /// Enables rendering of traditional forms (OpenType feature: trad).
+    TRADITIONAL / "traditional" => NS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL = 0x20,
+    /// Enables rendering of full-width variants (OpenType feature: fwid).
+    FULL_WIDTH / "full-width" => NS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH = 0x40,
+    /// Enables rendering of proportionally-spaced variants (OpenType feature: pwid).
+    PROPORTIONAL_WIDTH / "proportional-width" => NS_FONT_VARIANT_EAST_ASIAN_PROP_WIDTH = 0x80,
+    /// Enables display of ruby variant glyphs (OpenType feature: ruby).
+    RUBY / "ruby" => NS_FONT_VARIANT_EAST_ASIAN_RUBY = 0x100,
+}
+
 #[cfg(feature = "gecko")]
 impl VariantEastAsian {
     /// Obtain a specified value from a Gecko keyword value
     ///
     /// Intended for use with presentation attributes, not style structs
     pub fn from_gecko_keyword(kw: u16) -> Self {
         Self::from_bits_truncate(kw)
     }
 
     /// Transform into gecko keyword
     pub fn to_gecko_keyword(self) -> u16 {
         self.bits()
     }
 }
 
-impl ToCss for VariantEastAsian {
-    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: Write,
-    {
-        if self.is_empty() {
-            return dest.write_str("normal");
-        }
-
-        let mut has_any = false;
-
-        macro_rules! write_value {
-            ($ident:path => $str:expr) => {
-                if self.intersects($ident) {
-                    if has_any {
-                        dest.write_str(" ")?;
-                    }
-                    has_any = true;
-                    dest.write_str($str)?;
-                }
-            };
-        }
-
-        write_value!(VariantEastAsian::JIS78 => "jis78");
-        write_value!(VariantEastAsian::JIS83 => "jis83");
-        write_value!(VariantEastAsian::JIS90 => "jis90");
-        write_value!(VariantEastAsian::JIS04 => "jis04");
-        write_value!(VariantEastAsian::SIMPLIFIED => "simplified");
-        write_value!(VariantEastAsian::TRADITIONAL => "traditional");
-        write_value!(VariantEastAsian::FULL_WIDTH => "full-width");
-        write_value!(VariantEastAsian::PROPORTIONAL_WIDTH => "proportional-width");
-        write_value!(VariantEastAsian::RUBY => "ruby");
-
-        debug_assert!(has_any);
-        Ok(())
-    }
-}
-
 #[cfg(feature = "gecko")]
 impl_gecko_keyword_conversions!(VariantEastAsian, u16);
 
-impl SpecifiedValueInfo for VariantEastAsian {}
-
-/// Asserts that all variant-east-asian matches its NS_FONT_VARIANT_EAST_ASIAN_* value.
-#[cfg(feature = "gecko")]
-#[inline]
-pub fn assert_variant_east_asian_matches() {
-    use gecko_bindings::structs;
-
-    macro_rules! check_variant_east_asian {
-        ( $( $a:ident => $b:path),*, ) => {
-            if cfg!(debug_assertions) {
-                $(
-                    assert_eq!(structs::$a as u16, $b.bits());
-                )*
-            }
-        }
-    }
-
-    check_variant_east_asian! {
-        NS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH => VariantEastAsian::FULL_WIDTH,
-        NS_FONT_VARIANT_EAST_ASIAN_JIS04 => VariantEastAsian::JIS04,
-        NS_FONT_VARIANT_EAST_ASIAN_JIS78 => VariantEastAsian::JIS78,
-        NS_FONT_VARIANT_EAST_ASIAN_JIS83 => VariantEastAsian::JIS83,
-        NS_FONT_VARIANT_EAST_ASIAN_JIS90 => VariantEastAsian::JIS90,
-        NS_FONT_VARIANT_EAST_ASIAN_PROP_WIDTH => VariantEastAsian::PROPORTIONAL_WIDTH,
-        NS_FONT_VARIANT_EAST_ASIAN_RUBY => VariantEastAsian::RUBY,
-        NS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED => VariantEastAsian::SIMPLIFIED,
-        NS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL => VariantEastAsian::TRADITIONAL,
-    }
-}
-
 #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
 #[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToCss)]
 /// Allows control of glyph substitution and sizing in East Asian text.
 pub enum FontVariantEastAsian {
     /// Value variant with `variant-east-asian`
     Value(VariantEastAsian),
     /// System font variant
     #[css(skip)]
@@ -1495,133 +1479,116 @@ impl Parse for FontVariantEastAsian {
         if !result.is_empty() {
             Ok(FontVariantEastAsian::Value(result))
         } else {
             Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
         }
     }
 }
 
-bitflags! {
-    #[derive(MallocSizeOf)]
-    /// Variants of ligatures
-    pub struct VariantLigatures: u16 {
-        /// Specifies that common default features are enabled
-        const NORMAL = 0;
-        /// Specifies that all types of ligatures and contextual forms
-        /// covered by this property are explicitly disabled
-        const NONE = 0x01;
-        /// Enables display of common ligatures
-        const COMMON_LIGATURES = 0x02;
-        /// Disables display of common ligatures
-        const NO_COMMON_LIGATURES = 0x04;
-        /// Enables display of discretionary ligatures
-        const DISCRETIONARY_LIGATURES = 0x08;
-        /// Disables display of discretionary ligatures
-        const NO_DISCRETIONARY_LIGATURES = 0x10;
-        /// Enables display of historical ligatures
-        const HISTORICAL_LIGATURES = 0x20;
-        /// Disables display of historical ligatures
-        const NO_HISTORICAL_LIGATURES = 0x40;
-        /// Enables display of contextual alternates
-        const CONTEXTUAL = 0x80;
-        /// Disables display of contextual alternates
-        const NO_CONTEXTUAL = 0x100;
+macro_rules! impl_variant_ligatures {
+    {
+        $(
+            $(#[$($meta:tt)+])*
+            $ident:ident / $css:expr => $gecko:ident = $value:expr,
+        )+
+    } => {
+        bitflags! {
+            #[derive(MallocSizeOf)]
+            /// Variants of ligatures
+            pub struct VariantLigatures: u16 {
+                /// Specifies that common default features are enabled
+                const NORMAL = 0;
+                $(
+                    $(#[$($meta)+])*
+                    const $ident = $value;
+                )+
+            }
+        }
+
+        impl ToCss for VariantLigatures {
+            fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
+            where
+                W: Write,
+            {
+                if self.is_empty() {
+                    return dest.write_str("normal");
+                }
+                if self.contains(VariantLigatures::NONE) {
+                    return dest.write_str("none");
+                }
+
+                let mut writer = SequenceWriter::new(dest, " ");
+                $(
+                    if self.intersects(VariantLigatures::$ident) {
+                        writer.raw_item($css)?;
+                    }
+                )+
+                Ok(())
+            }
+        }
+
+        /// Asserts that all variant-east-asian matches its NS_FONT_VARIANT_EAST_ASIAN_* value.
+        #[cfg(feature = "gecko")]
+        #[inline]
+        pub fn assert_variant_ligatures_matches() {
+            use gecko_bindings::structs;
+            $(
+                debug_assert_eq!(structs::$gecko as u16, VariantLigatures::$ident.bits());
+            )+
+        }
+
+        impl SpecifiedValueInfo for VariantLigatures {
+            fn collect_completion_keywords(f: KeywordsCollectFn) {
+                f(&["normal", $($css,)+]);
+            }
+        }
     }
 }
 
+impl_variant_ligatures! {
+    /// Specifies that all types of ligatures and contextual forms
+    /// covered by this property are explicitly disabled
+    NONE / "none" => NS_FONT_VARIANT_LIGATURES_NONE = 0x01,
+    /// Enables display of common ligatures
+    COMMON_LIGATURES / "common-ligatures" => NS_FONT_VARIANT_LIGATURES_COMMON = 0x02,
+    /// Disables display of common ligatures
+    NO_COMMON_LIGATURES / "no-common-ligatures" => NS_FONT_VARIANT_LIGATURES_NO_COMMON = 0x04,
+    /// Enables display of discretionary ligatures
+    DISCRETIONARY_LIGATURES / "discretionary-ligatures" => NS_FONT_VARIANT_LIGATURES_DISCRETIONARY = 0x08,
+    /// Disables display of discretionary ligatures
+    NO_DISCRETIONARY_LIGATURES / "no-discretionary-ligatures" => NS_FONT_VARIANT_LIGATURES_NO_DISCRETIONARY = 0x10,
+    /// Enables display of historical ligatures
+    HISTORICAL_LIGATURES / "historical-ligatures" => NS_FONT_VARIANT_LIGATURES_HISTORICAL = 0x20,
+    /// Disables display of historical ligatures
+    NO_HISTORICAL_LIGATURES / "no-historical-ligatures" => NS_FONT_VARIANT_LIGATURES_NO_HISTORICAL = 0x40,
+    /// Enables display of contextual alternates
+    CONTEXTUAL / "contextual" => NS_FONT_VARIANT_LIGATURES_CONTEXTUAL = 0x80,
+    /// Disables display of contextual alternates
+    NO_CONTEXTUAL / "no-contextual" => NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL = 0x100,
+}
+
 #[cfg(feature = "gecko")]
 impl VariantLigatures {
     /// Obtain a specified value from a Gecko keyword value
     ///
     /// Intended for use with presentation attributes, not style structs
     pub fn from_gecko_keyword(kw: u16) -> Self {
         Self::from_bits_truncate(kw)
     }
 
     /// Transform into gecko keyword
     pub fn to_gecko_keyword(self) -> u16 {
         self.bits()
     }
 }
 
-impl ToCss for VariantLigatures {
-    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: Write,
-    {
-        if self.is_empty() {
-            return dest.write_str("normal");
-        }
-        if self.contains(VariantLigatures::NONE) {
-            return dest.write_str("none");
-        }
-
-        let mut has_any = false;
-
-        macro_rules! write_value {
-            ($ident:path => $str:expr) => {
-                if self.intersects($ident) {
-                    if has_any {
-                        dest.write_str(" ")?;
-                    }
-                    has_any = true;
-                    dest.write_str($str)?;
-                }
-            };
-        }
-
-        write_value!(VariantLigatures::COMMON_LIGATURES => "common-ligatures");
-        write_value!(VariantLigatures::NO_COMMON_LIGATURES => "no-common-ligatures");
-        write_value!(VariantLigatures::DISCRETIONARY_LIGATURES => "discretionary-ligatures");
-        write_value!(VariantLigatures::NO_DISCRETIONARY_LIGATURES => "no-discretionary-ligatures");
-        write_value!(VariantLigatures::HISTORICAL_LIGATURES => "historical-ligatures");
-        write_value!(VariantLigatures::NO_HISTORICAL_LIGATURES => "no-historical-ligatures");
-        write_value!(VariantLigatures::CONTEXTUAL => "contextual");
-        write_value!(VariantLigatures::NO_CONTEXTUAL => "no-contextual");
-
-        debug_assert!(has_any);
-        Ok(())
-    }
-}
-
-impl SpecifiedValueInfo for VariantLigatures {}
-
 #[cfg(feature = "gecko")]
 impl_gecko_keyword_conversions!(VariantLigatures, u16);
 
-/// Asserts that all variant-east-asian matches its NS_FONT_VARIANT_EAST_ASIAN_* value.
-#[cfg(feature = "gecko")]
-#[inline]
-pub fn assert_variant_ligatures_matches() {
-    use gecko_bindings::structs;
-
-    macro_rules! check_variant_ligatures {
-        ( $( $a:ident => $b:path),*, ) => {
-            if cfg!(debug_assertions) {
-                $(
-                    assert_eq!(structs::$a as u16, $b.bits());
-                )*
-            }
-        }
-    }
-
-    check_variant_ligatures! {
-        NS_FONT_VARIANT_LIGATURES_NONE => VariantLigatures::NONE,
-        NS_FONT_VARIANT_LIGATURES_COMMON => VariantLigatures::COMMON_LIGATURES,
-        NS_FONT_VARIANT_LIGATURES_NO_COMMON => VariantLigatures::NO_COMMON_LIGATURES,
-        NS_FONT_VARIANT_LIGATURES_DISCRETIONARY => VariantLigatures::DISCRETIONARY_LIGATURES,
-        NS_FONT_VARIANT_LIGATURES_NO_DISCRETIONARY => VariantLigatures::NO_DISCRETIONARY_LIGATURES,
-        NS_FONT_VARIANT_LIGATURES_HISTORICAL => VariantLigatures::HISTORICAL_LIGATURES,
-        NS_FONT_VARIANT_LIGATURES_NO_HISTORICAL => VariantLigatures::NO_HISTORICAL_LIGATURES,
-        NS_FONT_VARIANT_LIGATURES_CONTEXTUAL => VariantLigatures::CONTEXTUAL,
-        NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL => VariantLigatures::NO_CONTEXTUAL,
-    }
-}
-
 #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
 #[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToCss)]
 /// Ligatures and contextual forms are ways of combining glyphs
 /// to produce more harmonized forms
 pub enum FontVariantLigatures {
     /// Value variant with `variant-ligatures`
     Value(VariantLigatures),
     /// System font variant
@@ -1734,126 +1701,110 @@ impl Parse for FontVariantLigatures {
         if !result.is_empty() {
             Ok(FontVariantLigatures::Value(result))
         } else {
             Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
         }
     }
 }
 
-bitflags! {
-    #[derive(MallocSizeOf)]
-    /// Vairants of numeric values
-    pub struct VariantNumeric: u8 {
-        /// None of other variants are enabled.
-        const NORMAL = 0;
-        /// Enables display of lining numerals.
-        const LINING_NUMS = 0x01;
-        /// Enables display of old-style numerals.
-        const OLDSTYLE_NUMS = 0x02;
-        /// Enables display of proportional numerals.
-        const PROPORTIONAL_NUMS = 0x04;
-        /// Enables display of tabular numerals.
-        const TABULAR_NUMS = 0x08;
-        /// Enables display of lining diagonal fractions.
-        const DIAGONAL_FRACTIONS = 0x10;
-        /// Enables display of lining stacked fractions.
-        const STACKED_FRACTIONS = 0x20;
-        /// Enables display of letter forms used with ordinal numbers.
-        const ORDINAL = 0x80;
-        /// Enables display of slashed zeros.
-        const SLASHED_ZERO = 0x40;
+macro_rules! impl_variant_numeric {
+    {
+        $(
+            $(#[$($meta:tt)+])*
+            $ident:ident / $css:expr => $gecko:ident = $value:expr,
+        )+
+    } => {
+        bitflags! {
+            #[derive(MallocSizeOf)]
+            /// Vairants of numeric values
+            pub struct VariantNumeric: u8 {
+                /// None of other variants are enabled.
+                const NORMAL = 0;
+                $(
+                    $(#[$($meta)+])*
+                    const $ident = $value;
+                )+
+            }
+        }
+
+        impl ToCss for VariantNumeric {
+            fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
+            where
+                W: Write,
+            {
+                if self.is_empty() {
+                    return dest.write_str("normal");
+                }
+
+                let mut writer = SequenceWriter::new(dest, " ");
+                $(
+                    if self.intersects(VariantNumeric::$ident) {
+                        writer.raw_item($css)?;
+                    }
+                )+
+                Ok(())
+            }
+        }
+
+        /// Asserts that all variant-east-asian matches its NS_FONT_VARIANT_EAST_ASIAN_* value.
+        #[cfg(feature = "gecko")]
+        #[inline]
+        pub fn assert_variant_numeric_matches() {
+            use gecko_bindings::structs;
+            $(
+                debug_assert_eq!(structs::$gecko as u8, VariantNumeric::$ident.bits());
+            )+
+        }
+
+        impl SpecifiedValueInfo for VariantNumeric {
+            fn collect_completion_keywords(f: KeywordsCollectFn) {
+                f(&["normal", $($css,)+]);
+            }
+        }
     }
 }
 
+impl_variant_numeric! {
+    /// Enables display of lining numerals.
+    LINING_NUMS / "lining-nums" => NS_FONT_VARIANT_NUMERIC_LINING = 0x01,
+    /// Enables display of old-style numerals.
+    OLDSTYLE_NUMS / "oldstyle-nums" => NS_FONT_VARIANT_NUMERIC_OLDSTYLE = 0x02,
+    /// Enables display of proportional numerals.
+    PROPORTIONAL_NUMS / "proportional-nums" => NS_FONT_VARIANT_NUMERIC_PROPORTIONAL = 0x04,
+    /// Enables display of tabular numerals.
+    TABULAR_NUMS / "tabular-nums" => NS_FONT_VARIANT_NUMERIC_TABULAR = 0x08,
+    /// Enables display of lining diagonal fractions.
+    DIAGONAL_FRACTIONS / "diagonal-fractions" => NS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS = 0x10,
+    /// Enables display of lining stacked fractions.
+    STACKED_FRACTIONS / "stacked-fractions" => NS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS = 0x20,
+    /// Enables display of letter forms used with ordinal numbers.
+    ORDINAL / "ordinal" => NS_FONT_VARIANT_NUMERIC_ORDINAL = 0x80,
+    /// Enables display of slashed zeros.
+    SLASHED_ZERO / "slashed-zero" => NS_FONT_VARIANT_NUMERIC_SLASHZERO = 0x40,
+}
+
 #[cfg(feature = "gecko")]
 impl VariantNumeric {
     /// Obtain a specified value from a Gecko keyword value
     ///
     /// Intended for use with presentation attributes, not style structs
     pub fn from_gecko_keyword(kw: u8) -> Self {
         Self::from_bits_truncate(kw)
     }
 
     /// Transform into gecko keyword
     pub fn to_gecko_keyword(self) -> u8 {
         self.bits()
     }
 }
 
-impl ToCss for VariantNumeric {
-    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: Write,
-    {
-        if self.is_empty() {
-            return dest.write_str("normal");
-        }
-
-        let mut has_any = false;
-
-        macro_rules! write_value {
-            ($ident:path => $str:expr) => {
-                if self.intersects($ident) {
-                    if has_any {
-                        dest.write_str(" ")?;
-                    }
-                    has_any = true;
-                    dest.write_str($str)?;
-                }
-            };
-        }
-
-        write_value!(VariantNumeric::LINING_NUMS => "lining-nums");
-        write_value!(VariantNumeric::OLDSTYLE_NUMS => "oldstyle-nums");
-        write_value!(VariantNumeric::PROPORTIONAL_NUMS => "proportional-nums");
-        write_value!(VariantNumeric::TABULAR_NUMS => "tabular-nums");
-        write_value!(VariantNumeric::DIAGONAL_FRACTIONS => "diagonal-fractions");
-        write_value!(VariantNumeric::STACKED_FRACTIONS => "stacked-fractions");
-        write_value!(VariantNumeric::SLASHED_ZERO => "slashed-zero");
-        write_value!(VariantNumeric::ORDINAL => "ordinal");
-
-        debug_assert!(has_any);
-        Ok(())
-    }
-}
-
-impl SpecifiedValueInfo for VariantNumeric {}
-
 #[cfg(feature = "gecko")]
 impl_gecko_keyword_conversions!(VariantNumeric, u8);
 
-/// Asserts that all variant-east-asian matches its NS_FONT_VARIANT_EAST_ASIAN_* value.
-#[cfg(feature = "gecko")]
-#[inline]
-pub fn assert_variant_numeric_matches() {
-    use gecko_bindings::structs;
-
-    macro_rules! check_variant_numeric {
-        ( $( $a:ident => $b:path),*, ) => {
-            if cfg!(debug_assertions) {
-                $(
-                    assert_eq!(structs::$a as u8, $b.bits());
-                )*
-            }
-        }
-    }
-
-    check_variant_numeric! {
-        NS_FONT_VARIANT_NUMERIC_LINING => VariantNumeric::LINING_NUMS,
-        NS_FONT_VARIANT_NUMERIC_OLDSTYLE => VariantNumeric::OLDSTYLE_NUMS,
-        NS_FONT_VARIANT_NUMERIC_PROPORTIONAL => VariantNumeric::PROPORTIONAL_NUMS,
-        NS_FONT_VARIANT_NUMERIC_TABULAR => VariantNumeric::TABULAR_NUMS,
-        NS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS => VariantNumeric::DIAGONAL_FRACTIONS,
-        NS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS => VariantNumeric::STACKED_FRACTIONS,
-        NS_FONT_VARIANT_NUMERIC_SLASHZERO => VariantNumeric::SLASHED_ZERO,
-        NS_FONT_VARIANT_NUMERIC_ORDINAL => VariantNumeric::ORDINAL,
-    }
-}
-
 #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
 #[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToCss)]
 /// Specifies control over numerical forms.
 pub enum FontVariantNumeric {
     /// Value variant with `variant-numeric`
     Value(VariantNumeric),
     /// System font
     #[css(skip)]