diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-05-19 07:49:27 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-19 07:49:27 -0500 |
commit | 61d64daf4c5831e5e4428f76faaea874d8d5f4cd (patch) | |
tree | c56147fc2b65f2b9a43dc9f0c94bdebfe5446bc8 /components | |
parent | 448422c9a4f0cf28b92fd9e1479aa3d013b703f7 (diff) | |
parent | 96a23d9b73860fd0bc4fa089de1d4ca074654adc (diff) | |
download | servo-61d64daf4c5831e5e4428f76faaea874d8d5f4cd.tar.gz servo-61d64daf4c5831e5e4428f76faaea874d8d5f4cd.zip |
Auto merge of #16931 - nox:font-feature-descriptor, r=emilio
Support font-feature-settings as a @font-face descriptor
<!-- 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/16931)
<!-- Reviewable:end -->
Diffstat (limited to 'components')
-rw-r--r-- | components/style/font_face.rs | 23 | ||||
-rw-r--r-- | components/style/gecko/rules.rs | 40 | ||||
-rw-r--r-- | components/style/lib.rs | 3 | ||||
-rw-r--r-- | components/style/macros.rs | 115 | ||||
-rw-r--r-- | components/style/properties/longhand/font.mako.rs | 21 | ||||
-rw-r--r-- | components/style/values/mod.rs | 109 | ||||
-rw-r--r-- | components/style/values/specified/position.rs | 4 |
7 files changed, 191 insertions, 124 deletions
diff --git a/components/style/font_face.rs b/components/style/font_face.rs index 3d81476fd12..4c953c3b028 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -9,7 +9,7 @@ #![deny(missing_docs)] #[cfg(feature = "gecko")] -use computed_values::{font_style, font_weight, font_stretch}; +use computed_values::{font_feature_settings, font_stretch, font_style, font_weight}; use computed_values::font_family::FamilyName; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use cssparser::SourceLocation; @@ -72,6 +72,17 @@ impl ToCss for UrlSource { } } +/// A font-display value for a @font-face rule. +/// The font-display descriptor determines how a font face is displayed based +/// on whether and when it is downloaded and ready to use. +define_css_keyword_enum!(FontDisplay: + "auto" => Auto, + "block" => Block, + "swap" => Swap, + "fallback" => Fallback, + "optional" => Optional); +add_impls_for_keyword_enum!(FontDisplay); + /// Parse the block inside a `@font-face` rule. /// /// Note that the prelude parsing code lives in the `stylesheets` module. @@ -332,12 +343,20 @@ font_face_descriptors! { /// The stretch of this font face "font-stretch" stretch / mStretch: font_stretch::T = font_stretch::T::normal, + /// The display of this font face + "font-display" display / mDisplay: FontDisplay = FontDisplay::Auto, + /// The ranges of code points outside of which this font face should not be used. "unicode-range" unicode_range / mUnicodeRange: Vec<UnicodeRange> = vec![ UnicodeRange { start: 0, end: 0x10FFFF } ], - // FIXME: add font-feature-settings, font-language-override, and font-display + /// The feature settings of this font face. + "font-feature-settings" feature_settings / mFontFeatureSettings: font_feature_settings::T = { + font_feature_settings::T::Normal + }, + + // FIXME: add font-language-override. ] } diff --git a/components/style/gecko/rules.rs b/components/style/gecko/rules.rs index f41fcb1e0b1..80aa7a7acb2 100644 --- a/components/style/gecko/rules.rs +++ b/components/style/gecko/rules.rs @@ -4,18 +4,19 @@ //! Bindings for CSS Rule objects -use computed_values::{font_style, font_weight, font_stretch}; +use byteorder::{BigEndian, WriteBytesExt}; +use computed_values::{font_feature_settings, font_stretch, font_style, font_weight}; use computed_values::font_family::FamilyName; use counter_style; use cssparser::UnicodeRange; -use font_face::{FontFaceRuleData, Source}; +use font_face::{FontFaceRuleData, Source, FontDisplay}; use gecko_bindings::bindings; use gecko_bindings::structs::{self, nsCSSFontFaceRule, nsCSSValue}; use gecko_bindings::structs::{nsCSSCounterDesc, nsCSSCounterStyleRule}; use gecko_bindings::sugar::ns_css_value::ToNsCssValue; use gecko_bindings::sugar::refptr::{RefPtr, UniqueRefPtr}; use shared_lock::{ToCssWithGuard, SharedRwLockReadGuard}; -use std::fmt; +use std::{fmt, str}; /// A @font-face rule pub type FontFaceRule = RefPtr<nsCSSFontFaceRule>; @@ -32,6 +33,27 @@ impl ToNsCssValue for font_weight::T { } } +impl ToNsCssValue for font_feature_settings::T { + fn convert(self, nscssvalue: &mut nsCSSValue) { + match self { + font_feature_settings::T::Normal => nscssvalue.set_normal(), + font_feature_settings::T::Tag(tags) => { + nscssvalue.set_pair_list(tags.into_iter().map(|entry| { + let mut feature = nsCSSValue::null(); + let mut raw = [0u8; 4]; + (&mut raw[..]).write_u32::<BigEndian>(entry.tag).unwrap(); + feature.set_string(str::from_utf8(&raw).unwrap()); + + let mut index = nsCSSValue::null(); + index.set_integer(entry.value as i32); + + (feature, index) + })) + } + } + } +} + macro_rules! map_enum { ( $( @@ -115,6 +137,18 @@ impl ToNsCssValue for Vec<UnicodeRange> { } } +impl ToNsCssValue for FontDisplay { + fn convert(self, nscssvalue: &mut nsCSSValue) { + nscssvalue.set_enum(match self { + FontDisplay::Auto => structs::NS_FONT_DISPLAY_AUTO, + FontDisplay::Block => structs::NS_FONT_DISPLAY_BLOCK, + FontDisplay::Swap => structs::NS_FONT_DISPLAY_SWAP, + FontDisplay::Fallback => structs::NS_FONT_DISPLAY_FALLBACK, + FontDisplay::Optional => structs::NS_FONT_DISPLAY_OPTIONAL, + } as i32) + } +} + impl From<FontFaceRuleData> for FontFaceRule { fn from(data: FontFaceRuleData) -> FontFaceRule { let mut result = unsafe { diff --git a/components/style/lib.rs b/components/style/lib.rs index fc61dd1b001..7eb74bd6d42 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -83,6 +83,9 @@ extern crate time; #[allow(unused_extern_crates)] extern crate unicode_segmentation; +#[macro_use] +mod macros; + pub mod animation; #[allow(missing_docs)] // TODO. #[cfg(feature = "servo")] pub mod attr; diff --git a/components/style/macros.rs b/components/style/macros.rs new file mode 100644 index 00000000000..ce040891a74 --- /dev/null +++ b/components/style/macros.rs @@ -0,0 +1,115 @@ +/* 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/. */ + +//! Various macro helpers. + +macro_rules! define_numbered_css_keyword_enum { + ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+,) => { + define_numbered_css_keyword_enum!($name: $( $css => $variant = $value ),+); + }; + ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+) => { + #[allow(non_camel_case_types, missing_docs)] + #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] + pub enum $name { + $( $variant = $value ),+ + } + + impl $crate::parser::Parse for $name { + #[allow(missing_docs)] + fn parse(_context: &$crate::parser::ParserContext, input: &mut ::cssparser::Parser) -> Result<$name, ()> { + match_ignore_ascii_case! { &try!(input.expect_ident()), + $( $css => Ok($name::$variant), )+ + _ => Err(()) + } + } + } + + impl ::style_traits::values::ToCss for $name { + fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result + where W: ::std::fmt::Write, + { + match *self { + $( $name::$variant => dest.write_str($css) ),+ + } + } + } + } +} + +/// A macro used to implement HasViewportPercentage trait +/// for a given type that may never contain viewport units. +macro_rules! no_viewport_percentage { + ($name: ident) => { + impl $crate::values::HasViewportPercentage for $name { + #[inline] + fn has_viewport_percentage(&self) -> bool { + false + } + } + }; +} + +/// A macro for implementing `ComputedValueAsSpecified`, `Parse` +/// and `HasViewportPercentage` traits for the enums defined +/// using `define_css_keyword_enum` macro. +/// +/// NOTE: We should either move `Parse` trait to `style_traits` +/// or `define_css_keyword_enum` macro to this crate, but that +/// may involve significant cleanup in both the crates. +macro_rules! add_impls_for_keyword_enum { + ($name:ident) => { + impl $crate::parser::Parse for $name { + #[inline] + fn parse(_context: &$crate::parser::ParserContext, + input: &mut ::cssparser::Parser) + -> Result<Self, ()> { + $name::parse(input) + } + } + + impl $crate::values::computed::ComputedValueAsSpecified for $name {} + no_viewport_percentage!($name); + }; +} + +macro_rules! define_keyword_type { + ($name: ident, $css: expr) => { + #[derive(Clone, PartialEq, Copy)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[allow(missing_docs)] + pub struct $name; + + impl ::style_traits::ToCss for $name { + fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result where W: ::std::fmt::Write { + write!(dest, $css) + } + } + + impl $crate::properties::animated_properties::Animatable for $name { + #[inline] + fn add_weighted(&self, _other: &Self, _self_progress: f64, _other_progress: f64) + -> Result<Self, ()> { + Ok($name) + } + } + + impl fmt::Debug for $name { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, $css) + } + } + + impl $crate::parser::Parse for $name { + fn parse(_context: &$crate::parser::ParserContext, + input: &mut ::cssparser::Parser) + -> Result<$name, ()> { + input.expect_ident_matching($css).map(|_| $name) + } + } + + impl $crate::values::computed::ComputedValueAsSpecified for $name {} + no_viewport_percentage!($name); + }; +} diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 9d2ec4215d4..9461d1a688f 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -1803,14 +1803,14 @@ ${helpers.single_keyword_system("font-variant-position", use std::fmt; use style_traits::ToCss; - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum T { Normal, Tag(Vec<FeatureTagValue>) } - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct FeatureTagValue { pub tag: u32, @@ -1836,6 +1836,16 @@ ${helpers.single_keyword_system("font-variant-position", } } + impl Parse for T { + /// https://www.w3.org/TR/css-fonts-3/#propdef-font-feature-settings + fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { + if input.try(|i| i.expect_ident_matching("normal")).is_ok() { + return Ok(T::Normal); + } + input.parse_comma_separated(|i| FeatureTagValue::parse(context, i)).map(T::Tag) + } + } + impl ToCss for FeatureTagValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { use std::str; @@ -1908,12 +1918,7 @@ ${helpers.single_keyword_system("font-variant-position", /// normal | <feature-tag-value># pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { - if input.try(|input| input.expect_ident_matching("normal")).is_ok() { - Ok(SpecifiedValue::Value(computed_value::T::Normal)) - } else { - input.parse_comma_separated(|i| computed_value::FeatureTagValue::parse(context, i)) - .map(computed_value::T::Tag).map(SpecifiedValue::Value) - } + computed_value::T::parse(context, input).map(SpecifiedValue::Value) } </%helpers:longhand> diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index 4ce3d1f8dc1..63bcc366bad 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -11,81 +11,12 @@ use Atom; pub use cssparser::{RGBA, Token, Parser, serialize_identifier, serialize_string}; use parser::{Parse, ParserContext}; -use properties::animated_properties::Animatable; use std::ascii::AsciiExt; use std::borrow::Cow; use std::fmt::{self, Debug}; use std::hash; use style_traits::ToCss; -macro_rules! define_numbered_css_keyword_enum { - ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+,) => { - define_numbered_css_keyword_enum!($name: $( $css => $variant = $value ),+); - }; - ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+) => { - #[allow(non_camel_case_types, missing_docs)] - #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] - pub enum $name { - $( $variant = $value ),+ - } - - impl Parse for $name { - #[allow(missing_docs)] - fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<$name, ()> { - match_ignore_ascii_case! { &try!(input.expect_ident()), - $( $css => Ok($name::$variant), )+ - _ => Err(()) - } - } - } - - impl ToCss for $name { - fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result - where W: ::std::fmt::Write, - { - match *self { - $( $name::$variant => dest.write_str($css) ),+ - } - } - } - } -} - -/// A macro used to implement HasViewportPercentage trait -/// for a given type that may never contain viewport units. -macro_rules! no_viewport_percentage { - ($name: ident) => { - impl $crate::values::HasViewportPercentage for $name { - #[inline] - fn has_viewport_percentage(&self) -> bool { - false - } - } - }; -} - -/// A macro for implementing `ComputedValueAsSpecified`, `Parse` -/// and `HasViewportPercentage` traits for the enums defined -/// using `define_css_keyword_enum` macro. -/// -/// NOTE: We should either move `Parse` trait to `style_traits` -/// or `define_css_keyword_enum` macro to this crate, but that -/// may involve significant cleanup in both the crates. -macro_rules! add_impls_for_keyword_enum { - ($name:ident) => { - impl Parse for $name { - #[inline] - fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<Self, ()> { - $name::parse(input) - } - } - - impl ComputedValueAsSpecified for $name {} - no_viewport_percentage!($name); - }; -} - pub mod computed; pub mod generics; pub mod specified; @@ -112,46 +43,6 @@ impl<T: HasViewportPercentage> HasViewportPercentage for Box<T> { } } -use self::computed::ComputedValueAsSpecified; - -macro_rules! define_keyword_type { - ($name: ident, $css: expr) => { - #[derive(Clone, PartialEq, Copy)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - #[allow(missing_docs)] - pub struct $name; - - impl ::style_traits::ToCss for $name { - fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result where W: ::std::fmt::Write { - write!(dest, $css) - } - } - - impl Animatable for $name { - #[inline] - fn add_weighted(&self, _other: &Self, _self_progress: f64, _other_progress: f64) - -> Result<Self, ()> { - Ok($name) - } - } - - impl fmt::Debug for $name { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, $css) - } - } - - impl Parse for $name { - fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<$name, ()> { - input.expect_ident_matching($css).map(|_| $name) - } - } - - impl ComputedValueAsSpecified for $name {} - no_viewport_percentage!($name); - }; -} - define_keyword_type!(None_, "none"); define_keyword_type!(Auto, "auto"); define_keyword_type!(Normal, "normal"); diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs index c2991ede864..a4b4953c372 100644 --- a/components/style/values/specified/position.rs +++ b/components/style/values/specified/position.rs @@ -12,8 +12,8 @@ use parser::{Parse, ParserContext}; use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; -use values::computed::{CalcLengthOrPercentage, ComputedValueAsSpecified, Context}; -use values::computed::{LengthOrPercentage as ComputedLengthOrPercentage, ToComputedValue}; +use values::computed::{CalcLengthOrPercentage, LengthOrPercentage as ComputedLengthOrPercentage}; +use values::computed::{Context, ToComputedValue}; use values::generics::position::Position as GenericPosition; use values::specified::{AllowQuirks, LengthOrPercentage, Percentage}; |