servo: Merge #16568 - font-feature-settings gecko glue code (from WholeGrainGoats:master); r=Manishearth

<!-- Please describe your changes on the following line: -->
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.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #15975  (github issue number if applicable).

<!-- Either: -->
- [X] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: 01f169d8c1f52ae4c3eb53274b0613211415feb9

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : ca5f0e6f9c4804b5aa9eca0937b317bf99e9f035
This commit is contained in:
Juan C. Gonzalez-Zurita 2017-05-03 19:41:59 -05:00
parent 01d358ada0
commit 6cd7127c27
6 changed files with 79 additions and 17 deletions

1
servo/Cargo.lock generated
View File

@ -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)",

View File

@ -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;

View File

@ -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<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
use std::str;
use byteorder::{WriteBytesExt, NativeEndian};
let mut raw: Vec<u8> = vec!();
raw.write_u32::<NativeEndian>(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
/// <string> [ on | off | <integer> ]
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
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: <U+20, U+7E>
@ -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::<NativeEndian>().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 })
}
}
}

View File

@ -13,6 +13,7 @@ doctest = false
testing = ["style/testing"]
[dependencies]
byteorder = "1.0"
app_units = "0.4"
cssparser = "0.13"
euclid = "0.11"

View File

@ -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;

View File

@ -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::<NativeEndian>().unwrap();
let efgh = e_h_bytes.read_u32::<NativeEndian>().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);
}