From a3dbf1d27577471b09e66afbfc51148d1244c613 Mon Sep 17 00:00:00 2001 From: "Juan C. Gonzalez-Zurita" Date: Thu, 20 Apr 2017 15:20:02 -0400 Subject: [PATCH] font-feature-settings gecko glue code FeatureTagValue value property changed to use u32. ToCss for FeatureTagValue changed to allow conversion from u32 to string. Parse for the same struct updated to convert from string to u32. Added two functions to transfer settings to gecko and copy settings. --- Cargo.lock | 1 + components/style/properties/gecko.mako.rs | 37 ++++++++++++++++++- .../style/properties/longhand/font.mako.rs | 35 +++++++++++++----- tests/unit/style/Cargo.toml | 1 + tests/unit/style/lib.rs | 1 + tests/unit/style/parsing/font.rs | 21 ++++++++--- 6 files changed, 79 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e00ee76e97..e01e74c124a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2799,6 +2799,7 @@ name = "style_tests" version = "0.0.1" dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index e6aab102506..970b6a929a0 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1296,12 +1296,47 @@ fn static_assert() { skip_font_longhands = """font-family font-size font-size-adjust font-weight font-synthesis -x-lang font-variant-alternates font-variant-east-asian font-variant-ligatures - font-variant-numeric font-language-override""" + font-variant-numeric font-language-override + font-feature-settings""" %> <%self:impl_trait style_struct_name="Font" skip_longhands="${skip_font_longhands}" skip_additionals="*"> + pub fn set_font_feature_settings(&mut self, v: longhands::font_feature_settings::computed_value::T) { + use properties::longhands::font_feature_settings::computed_value::T; + + let current_settings = &mut self.gecko.mFont.fontFeatureSettings; + current_settings.clear_pod(); + + match v { + T::Normal => unsafe { current_settings.set_len_pod(0) }, + + T::Tag(feature_settings) => { + unsafe { current_settings.set_len_pod(feature_settings.len() as u32) }; + + for (current, feature) in current_settings.iter_mut().zip(feature_settings) { + current.mTag = feature.tag; + current.mValue = feature.value; + } + } + }; + } + + pub fn copy_font_feature_settings_from(&mut self, other: &Self ) { + let current_settings = &mut self.gecko.mFont.fontFeatureSettings; + let feature_settings = &other.gecko.mFont.fontFeatureSettings; + let settings_length = feature_settings.len() as u32; + + current_settings.clear_pod(); + unsafe { current_settings.set_len_pod(settings_length) }; + + for (current, feature) in current_settings.iter_mut().zip(feature_settings.iter()) { + current.mTag = feature.mTag; + current.mValue = feature.mValue; + } + } + pub fn set_font_family(&mut self, v: longhands::font_family::computed_value::T) { use properties::longhands::font_family::computed_value::FontFamily; use gecko_bindings::structs::FontFamilyType; diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 842b3279d90..761dd95e025 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -1754,7 +1754,7 @@ ${helpers.single_keyword_system("font-variant-position", spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-position", animation_value_type="none")} -<%helpers:longhand name="font-feature-settings" products="none" animation_value_type="none" extra_prefixes="moz" +<%helpers:longhand name="font-feature-settings" products="gecko" animation_value_type="none" extra_prefixes="moz" spec="https://drafts.csswg.org/css-fonts/#propdef-font-feature-settings"> use std::fmt; use style_traits::ToCss; @@ -1781,8 +1781,8 @@ ${helpers.single_keyword_system("font-variant-position", #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct FeatureTagValue { - pub tag: String, - pub value: i32 + pub tag: u32, + pub value: u32 } impl ToCss for T { @@ -1806,10 +1806,17 @@ ${helpers.single_keyword_system("font-variant-position", impl ToCss for FeatureTagValue { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + use std::str; + use byteorder::{WriteBytesExt, NativeEndian}; + + let mut raw: Vec = vec!(); + raw.write_u32::(self.tag).unwrap(); + let str_print = str::from_utf8(&raw).unwrap_or_default(); + match self.value { - 1 => write!(dest, "\"{}\"", self.tag), - 0 => write!(dest, "\"{}\" off", self.tag), - x => write!(dest, "\"{}\" {}", self.tag, x) + 1 => write!(dest, "\"{}\"", str_print), + 0 => write!(dest, "\"{}\" off",str_print), + x => write!(dest, "\"{}\" {}", str_print, x) } } } @@ -1818,6 +1825,11 @@ ${helpers.single_keyword_system("font-variant-position", /// https://www.w3.org/TR/css-fonts-3/#propdef-font-feature-settings /// [ on | off | ] fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + use std::io::Cursor; + use std::str; + use std::ops::Deref; + use byteorder::{ReadBytesExt, NativeEndian}; + let tag = try!(input.expect_string()); // allowed strings of length 4 containing chars: @@ -1827,22 +1839,25 @@ ${helpers.single_keyword_system("font-variant-position", return Err(()) } + let mut raw = Cursor::new(tag.as_bytes()); + let u_tag = raw.read_u32::().unwrap(); + if let Ok(value) = input.try(|input| input.expect_integer()) { // handle integer, throw if it is negative if value >= 0 { - Ok(FeatureTagValue { tag: tag.into_owned(), value: value }) + Ok(FeatureTagValue { tag: u_tag, value: value as u32 }) } else { Err(()) } } else if let Ok(_) = input.try(|input| input.expect_ident_matching("on")) { // on is an alias for '1' - Ok(FeatureTagValue { tag: tag.into_owned(), value: 1 }) + Ok(FeatureTagValue { tag: u_tag, value: 1 }) } else if let Ok(_) = input.try(|input| input.expect_ident_matching("off")) { // off is an alias for '0' - Ok(FeatureTagValue { tag: tag.into_owned(), value: 0 }) + Ok(FeatureTagValue { tag: u_tag, value: 0 }) } else { // empty value is an alias for '1' - Ok(FeatureTagValue { tag:tag.into_owned(), value: 1 }) + Ok(FeatureTagValue { tag: u_tag, value: 1 }) } } } diff --git a/tests/unit/style/Cargo.toml b/tests/unit/style/Cargo.toml index 09e0231931b..6a5dc7fdcbd 100644 --- a/tests/unit/style/Cargo.toml +++ b/tests/unit/style/Cargo.toml @@ -13,6 +13,7 @@ doctest = false testing = ["style/testing"] [dependencies] +byteorder = "1.0" app_units = "0.4" cssparser = "0.13" euclid = "0.11" diff --git a/tests/unit/style/lib.rs b/tests/unit/style/lib.rs index 0c2d9c8b53e..9d6d2b8e8be 100644 --- a/tests/unit/style/lib.rs +++ b/tests/unit/style/lib.rs @@ -6,6 +6,7 @@ #![feature(plugin, test)] extern crate app_units; +extern crate byteorder; extern crate cssparser; extern crate euclid; #[macro_use] extern crate html5ever; diff --git a/tests/unit/style/parsing/font.rs b/tests/unit/style/parsing/font.rs index cdb64961483..44bf1d4b47c 100644 --- a/tests/unit/style/parsing/font.rs +++ b/tests/unit/style/parsing/font.rs @@ -10,38 +10,47 @@ use style_traits::ToCss; #[test] fn font_feature_settings_should_parse_properly() { + use byteorder::{ReadBytesExt, NativeEndian}; + use std::io::Cursor; + let normal = parse_longhand!(font_feature_settings, "normal"); let normal_computed = computed_value::T::Normal; assert_eq!(normal, normal_computed); + let mut a_d_bytes = Cursor::new(b"abcd"); + let mut e_h_bytes = Cursor::new(b"efgh"); + + let abcd = a_d_bytes.read_u32::().unwrap(); + let efgh = e_h_bytes.read_u32::().unwrap(); + let on = parse_longhand!(font_feature_settings, "\"abcd\" on"); let on_computed = computed_value::T::Tag(vec![ - FeatureTagValue { tag: String::from("abcd"), value: 1 } + FeatureTagValue { tag: abcd, value: 1 } ]); assert_eq!(on, on_computed); let off = parse_longhand!(font_feature_settings, "\"abcd\" off"); let off_computed = computed_value::T::Tag(vec![ - FeatureTagValue { tag: String::from("abcd"), value: 0 } + FeatureTagValue { tag: abcd, value: 0 } ]); assert_eq!(off, off_computed); let no_value = parse_longhand!(font_feature_settings, "\"abcd\""); let no_value_computed = computed_value::T::Tag(vec![ - FeatureTagValue { tag: String::from("abcd"), value: 1 } + FeatureTagValue { tag: abcd, value: 1 } ]); assert_eq!(no_value, no_value_computed); let pos_integer = parse_longhand!(font_feature_settings, "\"abcd\" 100"); let pos_integer_computed = computed_value::T::Tag(vec![ - FeatureTagValue { tag: String::from("abcd"), value: 100 } + FeatureTagValue { tag: abcd, value: 100 } ]); assert_eq!(pos_integer, pos_integer_computed); let multiple = parse_longhand!(font_feature_settings, "\"abcd\" off, \"efgh\""); let multiple_computed = computed_value::T::Tag(vec![ - FeatureTagValue { tag: String::from("abcd"), value: 0 }, - FeatureTagValue { tag: String::from("efgh"), value: 1 } + FeatureTagValue { tag: abcd, value: 0 }, + FeatureTagValue { tag: efgh, value: 1 } ]); assert_eq!(multiple, multiple_computed); }