diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-11-13 10:20:22 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-13 10:20:22 -0600 |
commit | c261ff38c76c584fc93a4cded2ffe0d724d318fd (patch) | |
tree | 600873f8474908fa58da51af852ead8b93b26ff7 /components | |
parent | b74a89a14d51ac60fb7fb24881912c3e1829f34e (diff) | |
parent | 38eae7066692e043e3ef343b945ae735e9f93d7d (diff) | |
download | servo-c261ff38c76c584fc93a4cded2ffe0d724d318fd.tar.gz servo-c261ff38c76c584fc93a4cded2ffe0d724d318fd.zip |
Auto merge of #19188 - CYBAI:font-language-override-out-of-mako, r=emilio
style: Move font-language-override outside of mako
This is a sub-PR of #19015
r? emilio
---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #19187
- [x] These changes do not require tests
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/19188)
<!-- Reviewable:end -->
Diffstat (limited to 'components')
-rw-r--r-- | components/style/properties/longhand/font.mako.rs | 165 | ||||
-rw-r--r-- | components/style/values/computed/font.rs | 49 | ||||
-rw-r--r-- | components/style/values/computed/mod.rs | 2 | ||||
-rw-r--r-- | components/style/values/specified/font.rs | 97 | ||||
-rw-r--r-- | components/style/values/specified/mod.rs | 2 |
5 files changed, 157 insertions, 158 deletions
diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 08310021cdc..1f13ee06f0d 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -1224,162 +1224,15 @@ https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control- } </%helpers:longhand> -<%helpers:longhand name="font-language-override" products="gecko" animation_value_type="discrete" - extra_prefixes="moz" boxed="True" - flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER" - 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}; - - #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)] - pub enum SpecifiedValue { - Normal, - Override(String), - System(SystemFont) - } - - 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"), - SpecifiedValue::Override(ref lang) => lang.to_css(dest), - SpecifiedValue::System(sys) => sys.to_css(dest), - } - } - } - - 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 std::{fmt, str}; - use style_traits::ToCss; - use byteorder::{BigEndian, ByteOrder}; - - impl ToCss for T { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - if self.0 == 0 { - return dest.write_str("normal") - } - let mut buf = [0; 4]; - BigEndian::write_u32(&mut buf, self.0); - // Safe because we ensure it's ASCII during computing - let slice = if cfg!(debug_assertions) { - str::from_utf8(&buf).unwrap() - } else { - unsafe { str::from_utf8_unchecked(&buf) } - }; - slice.trim_right().to_css(dest) - } - } - - // font-language-override can only have a single three-letter - // OpenType "language system" tag, so we should be able to compute - // it and store it as a 32-bit integer - // (see http://www.microsoft.com/typography/otspec/languagetags.htm). - #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)] - pub struct T(pub u32); - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - computed_value::T(0) - } - - #[inline] - pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue::Normal - } - - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; - - #[inline] - fn to_computed_value(&self, _context: &Context) -> computed_value::T { - #[allow(unused_imports)] use std::ascii::AsciiExt; - match *self { - SpecifiedValue::Normal => computed_value::T(0), - SpecifiedValue::Override(ref lang) => { - if lang.is_empty() || lang.len() > 4 || !lang.is_ascii() { - return computed_value::T(0) - } - let mut computed_lang = lang.clone(); - while computed_lang.len() < 4 { - computed_lang.push(' '); - } - let bytes = computed_lang.into_bytes(); - computed_value::T(BigEndian::read_u32(&bytes)) - } - SpecifiedValue::System(_) => { - <%self:nongecko_unreachable> - _context.cached_system_font.as_ref().unwrap().font_language_override - </%self:nongecko_unreachable> - } - } - } - #[inline] - fn from_computed_value(computed: &computed_value::T) -> Self { - if computed.0 == 0 { - return SpecifiedValue::Normal - } - let mut buf = [0; 4]; - BigEndian::write_u32(&mut buf, computed.0); - SpecifiedValue::Override( - if cfg!(debug_assertions) { - String::from_utf8(buf.to_vec()).unwrap() - } else { - unsafe { String::from_utf8_unchecked(buf.to_vec()) } - } - ) - } - } - - /// normal | <string> - pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result<SpecifiedValue, ParseError<'i>> { - if input.try(|input| input.expect_ident_matching("normal")).is_ok() { - Ok(SpecifiedValue::Normal) - } else { - input.expect_string().map(|s| { - SpecifiedValue::Override(s.as_ref().to_owned()) - }).map_err(|e| e.into()) - } - } - - /// Used in @font-face. - impl Parse for SpecifiedValue { - fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result<Self, ParseError<'i>> { - parse(context, input) - } - } - - #[cfg(feature = "gecko")] - impl From<u32> for computed_value::T { - fn from(bits: u32) -> computed_value::T { - computed_value::T(bits) - } - } - - #[cfg(feature = "gecko")] - impl From<computed_value::T> for u32 { - fn from(v: computed_value::T) -> u32 { - v.0 - } - } -</%helpers:longhand> +${helpers.predefined_type("font-language-override", + "FontLanguageOverride", + products="gecko", + initial_value="computed::FontLanguageOverride::zero()", + initial_specified_value="specified::FontLanguageOverride::normal()", + animation_value_type="discrete", + extra_prefixes="moz", + flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", + spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-language-override")} <%helpers:longhand name="-x-lang" products="gecko" animation_value_type="none" internal="True" spec="Internal (not web-exposed)"> diff --git a/components/style/values/computed/font.rs b/components/style/values/computed/font.rs index 1613e64892b..d2b9dd618c8 100644 --- a/components/style/values/computed/font.rs +++ b/components/style/values/computed/font.rs @@ -5,6 +5,7 @@ //! Computed values for font properties use app_units::Au; +use byteorder::{BigEndian, ByteOrder}; use std::fmt; use style_traits::ToCss; use values::CSSFloat; @@ -276,6 +277,54 @@ impl FontVariantAlternates { } } +/// font-language-override can only have a single three-letter +/// OpenType "language system" tag, so we should be able to compute +/// it and store it as a 32-bit integer +/// (see http://www.microsoft.com/typography/otspec/languagetags.htm). +#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)] +pub struct FontLanguageOverride(pub u32); + +impl FontLanguageOverride { + #[inline] + /// Get computed default value of `font-language-override` with 0 + pub fn zero() -> FontLanguageOverride { + FontLanguageOverride(0) + } +} + +impl ToCss for FontLanguageOverride { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + use std::str; + + if self.0 == 0 { + return dest.write_str("normal") + } + let mut buf = [0; 4]; + BigEndian::write_u32(&mut buf, self.0); + // Safe because we ensure it's ASCII during computing + let slice = if cfg!(debug_assertions) { + str::from_utf8(&buf).unwrap() + } else { + unsafe { str::from_utf8_unchecked(&buf) } + }; + slice.trim_right().to_css(dest) + } +} + +#[cfg(feature = "gecko")] +impl From<u32> for FontLanguageOverride { + fn from(bits: u32) -> FontLanguageOverride { + FontLanguageOverride(bits) + } +} + +#[cfg(feature = "gecko")] +impl From<FontLanguageOverride> for u32 { + fn from(v: FontLanguageOverride) -> u32 { + v.0 + } +} + impl ToComputedValue for specified::MozScriptMinSize { type ComputedValue = MozScriptMinSize; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index bf3bbf712c5..862287f1973 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -37,7 +37,7 @@ pub use self::background::{BackgroundSize, BackgroundRepeat}; pub use self::border::{BorderImageSlice, BorderImageWidth, BorderImageSideWidth}; pub use self::border::{BorderRadius, BorderCornerRadius, BorderSpacing}; pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontWeight, FontVariantAlternates}; -pub use self::font::{MozScriptLevel, MozScriptMinSize, XTextZoom}; +pub use self::font::{FontLanguageOverride, MozScriptLevel, MozScriptMinSize, XTextZoom}; pub use self::box_::{AnimationIterationCount, AnimationName, ScrollSnapType, VerticalAlign}; pub use self::color::{Color, ColorPropertyValue, RGBAColor}; pub use self::effects::{BoxShadow, Filter, SimpleShadow}; diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index f0f2c2e9be8..a59fad9ec07 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -7,6 +7,7 @@ #[cfg(feature = "gecko")] use Atom; use app_units::Au; +use byteorder::{BigEndian, ByteOrder}; use cssparser::{Parser, Token}; use parser::{Parse, ParserContext}; use properties::longhands::system_font::SystemFont; @@ -938,6 +939,102 @@ impl From<FontSynthesis> for u8 { } } +#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToCss)] +/// Allows authors to explicitly specify the language system of the font, +/// overriding the language system implied by the content language +pub enum FontLanguageOverride { + /// When rendering with OpenType fonts, + /// the content language of the element is + /// used to infer the OpenType language system + Normal, + /// Single three-letter case-sensitive OpenType language system tag, + /// specifies the OpenType language system to be used instead of + /// the language system implied by the language of the element + Override(Box<str>), + /// Use system font + System(SystemFont) +} + +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 + } + } +} + +impl ToComputedValue for FontLanguageOverride { + type ComputedValue = computed::FontLanguageOverride; + + #[inline] + fn to_computed_value(&self, _context: &Context) -> computed::FontLanguageOverride { + #[allow(unused_imports)] use std::ascii::AsciiExt; + 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!() + } + } + } + } + #[inline] + fn from_computed_value(computed: &computed::FontLanguageOverride) -> Self { + if computed.0 == 0 { + return FontLanguageOverride::Normal + } + let mut buf = [0; 4]; + BigEndian::write_u32(&mut buf, computed.0); + FontLanguageOverride::Override( + if cfg!(debug_assertions) { + String::from_utf8(buf.to_vec()).unwrap() + } else { + unsafe { String::from_utf8_unchecked(buf.to_vec()) } + }.into_boxed_str() + ) + } +} + +impl Parse for FontLanguageOverride { + /// normal | <string> + fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<FontLanguageOverride, ParseError<'i>> { + if input.try(|input| input.expect_ident_matching("normal")).is_ok() { + return Ok(FontLanguageOverride::Normal) + } + + let string = input.expect_string()?; + Ok(FontLanguageOverride::Override(string.as_ref().to_owned().into_boxed_str())) + } +} + #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)] /// text-zoom. Enable if true, disable if false pub struct XTextZoom(pub bool); diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 3827b638e4b..013b6b803b4 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -31,7 +31,7 @@ pub use self::background::{BackgroundRepeat, BackgroundSize}; pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth}; pub use self::border::{BorderImageSideWidth, BorderRadius, BorderSideWidth, BorderSpacing}; pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontWeight, FontVariantAlternates}; -pub use self::font::{MozScriptLevel, MozScriptMinSize, XTextZoom}; +pub use self::font::{FontLanguageOverride, MozScriptLevel, MozScriptMinSize, XTextZoom}; pub use self::box_::{AnimationIterationCount, AnimationName, ScrollSnapType, VerticalAlign}; pub use self::color::{Color, ColorPropertyValue, RGBAColor}; pub use self::effects::{BoxShadow, Filter, SimpleShadow}; |