author | CYBAI <cyb.ai.815@gmail.com> |
Mon, 13 Nov 2017 10:20:22 -0600 | |
changeset 391588 | f062dbcb3bc106331eb8146a02f3b129c4cb4b3e |
parent 391587 | d720dddd8e4e22f6470efb35f0b795e3dd899376 |
child 391589 | 97b74ed9cfddf352e007f695e1712a3a4835c746 |
push id | 97297 |
push user | ncsoregi@mozilla.com |
push date | Mon, 13 Nov 2017 23:01:19 +0000 |
treeherder | mozilla-inbound@1f7a23820597 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | emilio |
milestone | 59.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
|
--- a/servo/components/style/properties/longhand/font.mako.rs +++ b/servo/components/style/properties/longhand/font.mako.rs @@ -1219,172 +1219,25 @@ https://drafts.csswg.org/css-fonts-4/#lo /// normal | <feature-tag-value># pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<SpecifiedValue, ParseError<'i>> { computed_value::T::parse(context, input) } </%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)"> pub use self::computed_value::T as SpecifiedValue; pub mod computed_value { use Atom; use std::fmt;
--- a/servo/components/style/values/computed/font.rs +++ b/servo/components/style/values/computed/font.rs @@ -1,15 +1,16 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ //! Computed values for font properties use app_units::Au; +use byteorder::{BigEndian, ByteOrder}; use std::fmt; use style_traits::ToCss; use values::CSSFloat; use values::animated::{ToAnimatedValue, ToAnimatedZero}; use values::computed::{Context, NonNegativeLength, ToComputedValue}; use values::specified::font as specified; use values::specified::length::{FontBaseSize, NoCalcLength}; @@ -271,16 +272,64 @@ pub type FontVariantAlternates = specifi impl FontVariantAlternates { #[inline] /// Get initial value with VariantAlternatesList pub fn get_initial_value() -> Self { specified::VariantAlternatesList(vec![].into_boxed_slice()) } } +/// 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; fn to_computed_value(&self, cx: &Context) -> MozScriptMinSize { // this value is used in the computation of font-size, so // we use the parent size let base_size = FontBaseSize::InheritedStyle; match self.0 {
--- a/servo/components/style/values/computed/mod.rs +++ b/servo/components/style/values/computed/mod.rs @@ -32,17 +32,17 @@ pub use app_units::Au; pub use properties::animated_properties::TransitionProperty; #[cfg(feature = "gecko")] pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems}; pub use self::angle::Angle; 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}; pub use self::flex::FlexBasis; pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect}; #[cfg(feature = "gecko")] pub use self::gecko::ScrollSnapPoint; pub use self::rect::LengthOrNumberRect;
--- a/servo/components/style/values/specified/font.rs +++ b/servo/components/style/values/specified/font.rs @@ -2,16 +2,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ //! Specified values for font properties #[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; #[allow(unused_imports)] use std::ascii::AsciiExt; use std::fmt; use style_traits::{ToCss, StyleParseErrorKind, ParseError}; use values::CustomIdent; @@ -933,16 +934,112 @@ impl From<FontSynthesis> for u8 { } if v.style { bits |= structs::NS_FONT_SYNTHESIS_STYLE as u8; } bits } } +#[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); impl Parse for XTextZoom { fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<XTextZoom, ParseError<'i>> { debug_assert!(false, "Should be set directly by presentation attributes only."); Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
--- a/servo/components/style/values/specified/mod.rs +++ b/servo/components/style/values/specified/mod.rs @@ -26,17 +26,17 @@ use values::specified::calc::CalcNode; pub use properties::animated_properties::TransitionProperty; pub use self::angle::Angle; #[cfg(feature = "gecko")] pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems}; 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}; pub use self::flex::FlexBasis; #[cfg(feature = "gecko")] pub use self::gecko::ScrollSnapPoint; pub use self::image::{ColorStop, EndingShape as GradientEndingShape, Gradient}; pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRect};