From 681df60191620a9881474bd56573492d9ec02cdb Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 21 Mar 2017 20:38:12 -0700 Subject: [PATCH] stylo: System font support for bitflag properties and font-language-override --- components/style/properties/data.py | 5 +- components/style/properties/gecko.mako.rs | 104 ++------ components/style/properties/helpers.mako.rs | 38 +++ .../style/properties/longhand/font.mako.rs | 240 +++++++++++++++--- .../style/properties/shorthand/font.mako.rs | 6 +- 5 files changed, 267 insertions(+), 126 deletions(-) diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 97519122a62b..50952d500cca 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -15,7 +15,10 @@ SYSTEM_FONT_LONGHANDS = """font_family font_size font_style font_variant_caps font_stretch font_kerning - font_variant_position font_weight font_size_adjust""".split() + font_variant_position font_weight + font_size_adjust font_variant_alternates + font_variant_ligatures font_variant_east_asian + font_variant_numeric font_language_override""".split() def maybe_moz_logical_alias(product, side, prop): if product == "gecko" and side[1]: diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index d124a45eaaf7..72cdf4e21a15 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -298,27 +298,6 @@ def set_gecko_property(ffi_name, expr): } -<%def name="impl_bitflags_setter(ident, gecko_ffi_name, bit_map, gecko_bit_prefix, cast_type='u8')"> - #[allow(non_snake_case)] - pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { - % for gecko_bit in bit_map.values(): - use gecko_bindings::structs::${gecko_bit_prefix}${gecko_bit}; - % endfor - - let mut bits: ${cast_type} = 0; - // FIXME: if we ensure that the Servo bitflags storage is the same - // as Gecko's one, we can just copy it. - % for servo_bit, gecko_bit in bit_map.iteritems(): - if v.contains(longhands::${ident}::${servo_bit}) { - bits |= ${gecko_bit_prefix}${gecko_bit} as ${cast_type}; - } - % endfor - - self.gecko.${gecko_ffi_name} = bits as ${cast_type}; - } - - - /// Convert a Servo color into an nscolor; with currentColor as 0 /// /// Call sites will need to be updated after https://bugzilla.mozilla.org/show_bug.cgi?id=760345 @@ -1371,7 +1350,10 @@ fn static_assert() { ${impl_simple_copy('font_weight', 'mFont.weight')} pub fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T { - unsafe { longhands::font_weight::computed_value::T::from_gecko_weight(self.gecko.mFont.weight) } + debug_assert!(self.gecko.mFont.weight >= 100); + debug_assert!(self.gecko.mFont.weight <= 900); + debug_assert!(self.gecko.mFont.weight % 10 == 0); + unsafe { transmute(self.gecko.mFont.weight) } } pub fn set_font_synthesis(&mut self, v: longhands::font_synthesis::computed_value::T) { @@ -1405,7 +1387,10 @@ fn static_assert() { pub fn clone_font_size_adjust(&self) -> longhands::font_size_adjust::computed_value::T { use properties::longhands::font_size_adjust::computed_value::T; - T::from_gecko_adjust(self.gecko.mFont.sizeAdjust) + match self.gecko.mFont.sizeAdjust { + -1.0 => T::None, + _ => T::Number(self.gecko.mFont.sizeAdjust), + } } #[allow(non_snake_case)] @@ -1429,20 +1414,10 @@ fn static_assert() { } ${impl_simple_copy('font_language_override', 'mFont.languageOverride')} - <% font_variant_alternates_map = { "HISTORICAL_FORMS": "HISTORICAL", - "STYLISTIC": "STYLISTIC", - "STYLESET": "STYLESET", - "CHARACTER_VARIANT": "CHARACTER_VARIANT", - "SWASH": "SWASH", - "ORNAMENTS": "ORNAMENTS", - "ANNOTATION": "ANNOTATION" } %> - // FIXME: Set alternateValues as well. - // self.gecko.mFont.alternateValues = xxx; - ${impl_bitflags_setter('font_variant_alternates', - 'mFont.variantAlternates', - font_variant_alternates_map, - 'NS_FONT_VARIANT_ALTERNATES_', - cast_type='u16')} + pub fn set_font_variant_alternates(&mut self, v: longhands::font_variant_alternates::computed_value::T) { + self.gecko.mFont.variantAlternates = v.to_gecko_keyword() + } + #[allow(non_snake_case)] pub fn copy_font_variant_alternates_from(&mut self, other: &Self) { self.gecko.mFont.variantAlternates = other.gecko.mFont.variantAlternates; @@ -1450,53 +1425,22 @@ fn static_assert() { // self.gecko.mFont.alternateValues = other.gecko.mFont.alternateValues; } - // servo_bit: gecko_bit - <% font_variant_ligatures_map = { "NONE": "NONE", - "COMMON_LIGATURES": "COMMON", - "NO_COMMON_LIGATURES": "NO_COMMON", - "DISCRETIONARY_LIGATURES": "DISCRETIONARY", - "NO_DISCRETIONARY_LIGATURES": "NO_DISCRETIONARY", - "HISTORICAL_LIGATURES": "HISTORICAL", - "NO_HISTORICAL_LIGATURES": "NO_HISTORICAL", - "CONTEXTUAL": "CONTEXTUAL", - "NO_CONTEXTUAL": "NO_CONTEXTUAL" } %> - ${impl_bitflags_setter('font_variant_ligatures', - 'mFont.variantLigatures', - font_variant_ligatures_map, - 'NS_FONT_VARIANT_LIGATURES_', - cast_type='u16')} + pub fn set_font_variant_ligatures(&mut self, v: longhands::font_variant_ligatures::computed_value::T) { + self.gecko.mFont.variantLigatures = v.to_gecko_keyword() + } + ${impl_simple_copy('font_variant_ligatures', 'mFont.variantLigatures')} - // servo_bit: gecko_bit - <% font_variant_east_asian_map = { "JIS78": "JIS78", - "JIS83": "JIS83", - "JIS90": "JIS90", - "JIS04": "JIS04", - "SIMPLIFIED": "SIMPLIFIED", - "TRADITIONAL": "TRADITIONAL", - "FULL_WIDTH": "FULL_WIDTH", - "PROPORTIONAL_WIDTH": "PROP_WIDTH", - "RUBY": "RUBY" } %> - ${impl_bitflags_setter('font_variant_east_asian', - 'mFont.variantEastAsian', - font_variant_east_asian_map, - 'NS_FONT_VARIANT_EAST_ASIAN_', - cast_type='u16')} + pub fn set_font_variant_east_asian(&mut self, v: longhands::font_variant_east_asian::computed_value::T) { + self.gecko.mFont.variantEastAsian = v.to_gecko_keyword() + } + ${impl_simple_copy('font_variant_east_asian', 'mFont.variantEastAsian')} - // servo_bit: gecko_bit - <% font_variant_numeric_map = { "LINING_NUMS": "LINING", - "OLDSTYLE_NUMS": "OLDSTYLE", - "PROPORTIONAL_NUMS": "PROPORTIONAL", - "TABULAR_NUMS": "TABULAR", - "DIAGONAL_FRACTIONS": "DIAGONAL_FRACTIONS", - "STACKED_FRACTIONS": "STACKED_FRACTIONS", - "SLASHED_ZERO": "SLASHZERO", - "ORDINAL": "ORDINAL" } %> - ${impl_bitflags_setter('font_variant_numeric', - 'mFont.variantNumeric', - font_variant_numeric_map, - 'NS_FONT_VARIANT_NUMERIC_')} + pub fn set_font_variant_numeric(&mut self, v: longhands::font_variant_numeric::computed_value::T) { + self.gecko.mFont.variantNumeric = v.to_gecko_keyword() + } + ${impl_simple_copy('font_variant_numeric', 'mFont.variantNumeric')} diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 978bce1ea44d..4f425bc53625 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -566,6 +566,44 @@ } +<%def name="gecko_bitflags_conversion(bit_map, gecko_bit_prefix, type, kw_type='u8')"> + #[cfg(feature = "gecko")] + impl ${type} { + /// Obtain a specified value from a Gecko keyword value + /// + /// Intended for use with presentation attributes, not style structs + pub fn from_gecko_keyword(kw: ${kw_type}) -> Self { + % for gecko_bit in bit_map.values(): + use gecko_bindings::structs::${gecko_bit_prefix}${gecko_bit}; + % endfor + + let mut bits = ${type}::empty(); + % for servo_bit, gecko_bit in bit_map.iteritems(): + if kw & (${gecko_bit_prefix}${gecko_bit} as ${kw_type}) != 0 { + bits |= ${servo_bit}; + } + % endfor + bits + } + + pub fn to_gecko_keyword(self) -> ${kw_type} { + % for gecko_bit in bit_map.values(): + use gecko_bindings::structs::${gecko_bit_prefix}${gecko_bit}; + % endfor + + let mut bits: ${kw_type} = 0; + // FIXME: if we ensure that the Servo bitflags storage is the same + // as Gecko's one, we can just copy it. + % for servo_bit, gecko_bit in bit_map.iteritems(): + if self.contains(${servo_bit}) { + bits |= ${gecko_bit_prefix}${gecko_bit} as ${kw_type}; + } + % endfor + bits + } + } + + <%def name="single_keyword_computed(name, values, vector=False, extra_specified=None, needs_conversion=False, **kwargs)"> <% diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 4bf21656772f..99d16bdc23be 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -16,6 +16,52 @@ %endif +// Define ToComputedValue, ToCss, and other boilerplate for a specified value +// which is of the form `enum SpecifiedValue {Value(..), System(SystemFont)}` +<%def name="simple_system_boilerplate(name)"> + impl ToCss for SpecifiedValue { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + SpecifiedValue::Value(v) => v.to_css(dest), + SpecifiedValue::System(_) => Ok(()) + } + } + } + + + impl SpecifiedValue { + pub fn system_font(f: SystemFont) -> Self { + SpecifiedValue::System(f) + } + pub fn get_system(&self) -> Option { + if let SpecifiedValue::System(s) = *self { + Some(s) + } else { + None + } + } + } + + impl ToComputedValue for SpecifiedValue { + type ComputedValue = computed_value::T; + + fn to_computed_value(&self, context: &Context) -> computed_value::T { + match *self { + SpecifiedValue::Value(v) => v, + SpecifiedValue::System(_) => { + <%self:nongecko_unreachable> + context.style.cached_system_font.as_ref().unwrap().${name} + + } + } + } + + fn from_computed_value(other: &computed_value::T) -> Self { + SpecifiedValue::Value(*other) + } + } + + <%helpers:longhand name="font-family" animation_type="none" need_index="True" spec="https://drafts.csswg.org/css-fonts/#propdef-font-family"> use properties::longhands::system_font::SystemFont; @@ -1036,17 +1082,16 @@ ${helpers.single_keyword_system("font-kerning", /// https://github.com/servo/servo/issues/15957 <%helpers:longhand name="font-variant-alternates" products="gecko" animation_type="none" spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-alternates"> + use properties::longhands::system_font::SystemFont; use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; - use values::computed::ComputedValueAsSpecified; - impl ComputedValueAsSpecified for SpecifiedValue {} no_viewport_percentage!(SpecifiedValue); bitflags! { #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub flags SpecifiedValue: u8 { + pub flags VariantAlternates: u8 { const NORMAL = 0, const HISTORICAL_FORMS = 0x01, const STYLISTIC = 0x02, @@ -1058,7 +1103,25 @@ ${helpers.single_keyword_system("font-kerning", } } - impl ToCss for SpecifiedValue { + #[derive(Debug, Clone, PartialEq)] + pub enum SpecifiedValue { + Value(VariantAlternates), + System(SystemFont) + } + + <%self:simple_system_boilerplate name="font_variant_alternates"> + + <% font_variant_alternates_map = { "HISTORICAL_FORMS": "HISTORICAL", + "STYLISTIC": "STYLISTIC", + "STYLESET": "STYLESET", + "CHARACTER_VARIANT": "CHARACTER_VARIANT", + "SWASH": "SWASH", + "ORNAMENTS": "ORNAMENTS", + "ANNOTATION": "ANNOTATION" } %> + ${helpers.gecko_bitflags_conversion(font_variant_alternates_map, 'NS_FONT_VARIANT_ALTERNATES_', + 'VariantAlternates', kw_type='u16')} + + impl ToCss for VariantAlternates { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { if self.is_empty() { return dest.write_str("normal") @@ -1092,7 +1155,7 @@ ${helpers.single_keyword_system("font-kerning", } pub mod computed_value { - pub type T = super::SpecifiedValue; + pub type T = super::VariantAlternates; } #[inline] pub fn get_initial_value() -> computed_value::T { @@ -1100,7 +1163,7 @@ ${helpers.single_keyword_system("font-kerning", } #[inline] pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue::empty() + SpecifiedValue::Value(VariantAlternates::empty()) } /// normal | @@ -1112,10 +1175,10 @@ ${helpers.single_keyword_system("font-kerning", /// ornaments() || /// annotation() ] pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - let mut result = SpecifiedValue::empty(); + let mut result = VariantAlternates::empty(); if input.try(|input| input.expect_ident_matching("normal")).is_ok() { - return Ok(result) + return Ok(SpecifiedValue::Value(result)) } while let Ok(ident) = input.try(|input| input.expect_ident()) { @@ -1136,7 +1199,7 @@ ${helpers.single_keyword_system("font-kerning", } if !result.is_empty() { - Ok(result) + Ok(SpecifiedValue::Value(result)) } else { Err(()) } @@ -1155,17 +1218,16 @@ macro_rules! exclusive_value { <%helpers:longhand name="font-variant-east-asian" products="gecko" animation_type="none" spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-east-asian"> + use properties::longhands::system_font::SystemFont; use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; - use values::computed::ComputedValueAsSpecified; - impl ComputedValueAsSpecified for SpecifiedValue {} no_viewport_percentage!(SpecifiedValue); bitflags! { #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub flags SpecifiedValue: u16 { + pub flags VariantEastAsian: u16 { const NORMAL = 0, const JIS78 = 0x01, const JIS83 = 0x02, @@ -1179,7 +1241,31 @@ macro_rules! exclusive_value { } } - impl ToCss for SpecifiedValue { + + #[derive(Debug, Clone, PartialEq)] + pub enum SpecifiedValue { + Value(VariantEastAsian), + System(SystemFont) + } + + <%self:simple_system_boilerplate name="font_variant_east_asian"> + + // servo_bit: gecko_bit + <% font_variant_east_asian_map = { "JIS78": "JIS78", + "JIS83": "JIS83", + "JIS90": "JIS90", + "JIS04": "JIS04", + "SIMPLIFIED": "SIMPLIFIED", + "TRADITIONAL": "TRADITIONAL", + "FULL_WIDTH": "FULL_WIDTH", + "PROPORTIONAL_WIDTH": "PROP_WIDTH", + "RUBY": "RUBY" } %> + + ${helpers.gecko_bitflags_conversion(font_variant_east_asian_map, 'NS_FONT_VARIANT_EAST_ASIAN_', + 'VariantEastAsian', kw_type='u16')} + + + impl ToCss for VariantEastAsian { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { if self.is_empty() { return dest.write_str("normal") @@ -1215,7 +1301,7 @@ macro_rules! exclusive_value { } pub mod computed_value { - pub type T = super::SpecifiedValue; + pub type T = super::VariantEastAsian; } #[inline] pub fn get_initial_value() -> computed_value::T { @@ -1223,7 +1309,7 @@ macro_rules! exclusive_value { } #[inline] pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue::empty() + SpecifiedValue::Value(VariantEastAsian::empty()) } /// normal | [ || || ruby ] @@ -1232,10 +1318,10 @@ macro_rules! exclusive_value { <% east_asian_variant_values = "JIS78 | JIS83 | JIS90 | JIS04 | SIMPLIFIED | TRADITIONAL" %> <% east_asian_width_values = "FULL_WIDTH | PROPORTIONAL_WIDTH" %> pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - let mut result = SpecifiedValue::empty(); + let mut result = VariantEastAsian::empty(); if input.try(|input| input.expect_ident_matching("normal")).is_ok() { - return Ok(result) + return Ok(SpecifiedValue::Value(result)) } while let Ok(ident) = input.try(|input| input.expect_ident()) { @@ -1264,7 +1350,7 @@ macro_rules! exclusive_value { } if !result.is_empty() { - Ok(result) + Ok(SpecifiedValue::Value(result)) } else { Err(()) } @@ -1273,17 +1359,16 @@ macro_rules! exclusive_value { <%helpers:longhand name="font-variant-ligatures" products="gecko" animation_type="none" spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-ligatures"> + use properties::longhands::system_font::SystemFont; use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; - use values::computed::ComputedValueAsSpecified; - impl ComputedValueAsSpecified for SpecifiedValue {} no_viewport_percentage!(SpecifiedValue); bitflags! { #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub flags SpecifiedValue: u16 { + pub flags VariantLigatures: u16 { const NORMAL = 0, const NONE = 0x01, const COMMON_LIGATURES = 0x02, @@ -1297,7 +1382,30 @@ macro_rules! exclusive_value { } } - impl ToCss for SpecifiedValue { + + #[derive(Debug, Clone, PartialEq)] + pub enum SpecifiedValue { + Value(VariantLigatures), + System(SystemFont) + } + + <%self:simple_system_boilerplate name="font_variant_ligatures"> + + // servo_bit: gecko_bit + <% font_variant_ligatures_map = { "NONE": "NONE", + "COMMON_LIGATURES": "COMMON", + "NO_COMMON_LIGATURES": "NO_COMMON", + "DISCRETIONARY_LIGATURES": "DISCRETIONARY", + "NO_DISCRETIONARY_LIGATURES": "NO_DISCRETIONARY", + "HISTORICAL_LIGATURES": "HISTORICAL", + "NO_HISTORICAL_LIGATURES": "NO_HISTORICAL", + "CONTEXTUAL": "CONTEXTUAL", + "NO_CONTEXTUAL": "NO_CONTEXTUAL" } %> + + ${helpers.gecko_bitflags_conversion(font_variant_ligatures_map, 'NS_FONT_VARIANT_LIGATURES_', + 'VariantLigatures', kw_type='u16')} + + impl ToCss for VariantLigatures { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { if self.is_empty() { return dest.write_str("normal") @@ -1335,7 +1443,7 @@ macro_rules! exclusive_value { } pub mod computed_value { - pub type T = super::SpecifiedValue; + pub type T = super::VariantLigatures; } #[inline] pub fn get_initial_value() -> computed_value::T { @@ -1343,7 +1451,7 @@ macro_rules! exclusive_value { } #[inline] pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue::empty() + SpecifiedValue::Value(VariantLigatures::empty()) } /// normal | none | @@ -1360,13 +1468,13 @@ macro_rules! exclusive_value { <% historical_lig_values = "HISTORICAL_LIGATURES | NO_HISTORICAL_LIGATURES" %> <% contextual_alt_values = "CONTEXTUAL | NO_CONTEXTUAL" %> pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - let mut result = SpecifiedValue::empty(); + let mut result = VariantLigatures::empty(); if input.try(|input| input.expect_ident_matching("normal")).is_ok() { - return Ok(result) + return Ok(SpecifiedValue::Value(result)) } if input.try(|input| input.expect_ident_matching("none")).is_ok() { - return Ok(NONE) + return Ok(SpecifiedValue::Value(NONE)) } while let Ok(ident) = input.try(|input| input.expect_ident()) { @@ -1393,7 +1501,7 @@ macro_rules! exclusive_value { } if !result.is_empty() { - Ok(result) + Ok(SpecifiedValue::Value(result)) } else { Err(()) } @@ -1402,17 +1510,16 @@ macro_rules! exclusive_value { <%helpers:longhand name="font-variant-numeric" products="gecko" animation_type="none" spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-numeric"> + use properties::longhands::system_font::SystemFont; use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; - use values::computed::ComputedValueAsSpecified; - impl ComputedValueAsSpecified for SpecifiedValue {} no_viewport_percentage!(SpecifiedValue); bitflags! { #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub flags SpecifiedValue: u8 { + pub flags VariantNumeric: u8 { const NORMAL = 0, const LINING_NUMS = 0x01, const OLDSTYLE_NUMS = 0x02, @@ -1425,7 +1532,31 @@ macro_rules! exclusive_value { } } - impl ToCss for SpecifiedValue { + + + #[derive(Debug, Clone, PartialEq)] + pub enum SpecifiedValue { + Value(VariantNumeric), + System(SystemFont) + } + + <%self:simple_system_boilerplate name="font_variant_numeric"> + + + // servo_bit: gecko_bit + <% font_variant_numeric_map = { "LINING_NUMS": "LINING", + "OLDSTYLE_NUMS": "OLDSTYLE", + "PROPORTIONAL_NUMS": "PROPORTIONAL", + "TABULAR_NUMS": "TABULAR", + "DIAGONAL_FRACTIONS": "DIAGONAL_FRACTIONS", + "STACKED_FRACTIONS": "STACKED_FRACTIONS", + "SLASHED_ZERO": "SLASHZERO", + "ORDINAL": "ORDINAL" } %> + + ${helpers.gecko_bitflags_conversion(font_variant_numeric_map, 'NS_FONT_VARIANT_NUMERIC_', + 'VariantNumeric')} + + impl ToCss for VariantNumeric { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { if self.is_empty() { return dest.write_str("normal") @@ -1460,7 +1591,7 @@ macro_rules! exclusive_value { } pub mod computed_value { - pub type T = super::SpecifiedValue; + pub type T = super::VariantNumeric; } #[inline] pub fn get_initial_value() -> computed_value::T { @@ -1468,7 +1599,7 @@ macro_rules! exclusive_value { } #[inline] pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue::empty() + SpecifiedValue::Value(VariantNumeric::empty()) } /// normal | @@ -1484,10 +1615,10 @@ macro_rules! exclusive_value { <% numeric_spacing_values = "PROPORTIONAL_NUMS | TABULAR_NUMS" %> <% numeric_fraction_values = "DIAGONAL_FRACTIONS | STACKED_FRACTIONS" %> pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - let mut result = SpecifiedValue::empty(); + let mut result = VariantNumeric::empty(); if input.try(|input| input.expect_ident_matching("normal")).is_ok() { - return Ok(result) + return Ok(SpecifiedValue::Value(result)) } while let Ok(ident) = input.try(|input| input.expect_ident()) { @@ -1514,7 +1645,7 @@ macro_rules! exclusive_value { } if !result.is_empty() { - Ok(result) + Ok(SpecifiedValue::Value(result)) } else { Err(()) } @@ -1641,6 +1772,7 @@ ${helpers.single_keyword_system("font-variant-position", <%helpers:longhand name="font-language-override" products="gecko" animation_type="none" extra_prefixes="moz" spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-language-override"> + use properties::longhands::system_font::SystemFont; use std::fmt; use style_traits::ToCss; use byteorder::{BigEndian, ByteOrder}; @@ -1652,6 +1784,7 @@ ${helpers.single_keyword_system("font-variant-position", pub enum SpecifiedValue { Normal, Override(String), + System(SystemFont) } impl ToCss for SpecifiedValue { @@ -1661,6 +1794,20 @@ ${helpers.single_keyword_system("font-variant-position", SpecifiedValue::Normal => dest.write_str("normal"), SpecifiedValue::Override(ref lang) => cssparser::serialize_string(lang, dest), + SpecifiedValue::System(_) => Ok(()) + } + } + } + + impl SpecifiedValue { + pub fn system_font(f: SystemFont) -> Self { + SpecifiedValue::System(f) + } + pub fn get_system(&self) -> Option { + if let SpecifiedValue::System(s) = *self { + Some(s) + } else { + None } } } @@ -1711,7 +1858,7 @@ ${helpers.single_keyword_system("font-variant-position", type ComputedValue = computed_value::T; #[inline] - fn to_computed_value(&self, _: &Context) -> computed_value::T { + fn to_computed_value(&self, context: &Context) -> computed_value::T { use std::ascii::AsciiExt; match *self { SpecifiedValue::Normal => computed_value::T(0), @@ -1726,6 +1873,11 @@ ${helpers.single_keyword_system("font-variant-position", let bytes = computed_lang.into_bytes(); computed_value::T(BigEndian::read_u32(&bytes)) } + SpecifiedValue::System(_) => { + <%self:nongecko_unreachable> + context.style.cached_system_font.as_ref().unwrap().font_language_override + + } } } #[inline] @@ -1959,7 +2111,11 @@ ${helpers.single_keyword("-moz-math-variant", -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() + font_kerning font_variant_position font_variant_alternates + font_variant_ligatures font_variant_east_asian + font_variant_numeric""".split() + kw_cast = """font_style font_variant_caps font_stretch + font_kerning font_variant_position""".split() %> #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum SystemFont { @@ -2025,9 +2181,13 @@ ${helpers.single_keyword("-moz-math-variant", 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 + system.${to_camel_case_lower(kwprop.replace('font_', ''))} + % if kwprop in kw_cast: + as u32 + % endif ), % endfor + font_language_override: longhands::font_language_override::computed_value::T(system.languageOverride), system_font: *self, }; unsafe { bindings::Gecko_nsFont_Destroy(&mut system); } diff --git a/components/style/properties/shorthand/font.mako.rs b/components/style/properties/shorthand/font.mako.rs index 30b06c524b3f..8be68523ff59 100644 --- a/components/style/properties/shorthand/font.mako.rs +++ b/components/style/properties/shorthand/font.mako.rs @@ -46,11 +46,7 @@ % for name in SYSTEM_FONT_LONGHANDS: ${name}: ${name}::SpecifiedValue::system_font(sys), % endfor - % for name in gecko_sub_properties + "variant_caps stretch".split(): - % if "font_" + name not in SYSTEM_FONT_LONGHANDS: - font_${name}: font_${name}::get_initial_specified_value(), - % endif - % endfor + // line-height is just reset to initial line_height: line_height::get_initial_specified_value(), }) }