mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
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.
This commit is contained in:
parent
3905b5af18
commit
a3dbf1d275
6 changed files with 79 additions and 17 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2799,6 +2799,7 @@ name = "style_tests"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"html5ever 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -1296,12 +1296,47 @@ fn static_assert() {
|
||||||
skip_font_longhands = """font-family font-size font-size-adjust font-weight
|
skip_font_longhands = """font-family font-size font-size-adjust font-weight
|
||||||
font-synthesis -x-lang font-variant-alternates
|
font-synthesis -x-lang font-variant-alternates
|
||||||
font-variant-east-asian font-variant-ligatures
|
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"
|
<%self:impl_trait style_struct_name="Font"
|
||||||
skip_longhands="${skip_font_longhands}"
|
skip_longhands="${skip_font_longhands}"
|
||||||
skip_additionals="*">
|
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) {
|
pub fn set_font_family(&mut self, v: longhands::font_family::computed_value::T) {
|
||||||
use properties::longhands::font_family::computed_value::FontFamily;
|
use properties::longhands::font_family::computed_value::FontFamily;
|
||||||
use gecko_bindings::structs::FontFamilyType;
|
use gecko_bindings::structs::FontFamilyType;
|
||||||
|
|
|
@ -1754,7 +1754,7 @@ ${helpers.single_keyword_system("font-variant-position",
|
||||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-position",
|
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-position",
|
||||||
animation_value_type="none")}
|
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">
|
spec="https://drafts.csswg.org/css-fonts/#propdef-font-feature-settings">
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
@ -1781,8 +1781,8 @@ ${helpers.single_keyword_system("font-variant-position",
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct FeatureTagValue {
|
pub struct FeatureTagValue {
|
||||||
pub tag: String,
|
pub tag: u32,
|
||||||
pub value: i32
|
pub value: u32
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for T {
|
impl ToCss for T {
|
||||||
|
@ -1806,10 +1806,17 @@ ${helpers.single_keyword_system("font-variant-position",
|
||||||
|
|
||||||
impl ToCss for FeatureTagValue {
|
impl ToCss for FeatureTagValue {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
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 {
|
match self.value {
|
||||||
1 => write!(dest, "\"{}\"", self.tag),
|
1 => write!(dest, "\"{}\"", str_print),
|
||||||
0 => write!(dest, "\"{}\" off", self.tag),
|
0 => write!(dest, "\"{}\" off",str_print),
|
||||||
x => write!(dest, "\"{}\" {}", self.tag, x)
|
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
|
/// https://www.w3.org/TR/css-fonts-3/#propdef-font-feature-settings
|
||||||
/// <string> [ on | off | <integer> ]
|
/// <string> [ on | off | <integer> ]
|
||||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
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());
|
let tag = try!(input.expect_string());
|
||||||
|
|
||||||
// allowed strings of length 4 containing chars: <U+20, U+7E>
|
// allowed strings of length 4 containing chars: <U+20, U+7E>
|
||||||
|
@ -1827,22 +1839,25 @@ ${helpers.single_keyword_system("font-variant-position",
|
||||||
return Err(())
|
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()) {
|
if let Ok(value) = input.try(|input| input.expect_integer()) {
|
||||||
// handle integer, throw if it is negative
|
// handle integer, throw if it is negative
|
||||||
if value >= 0 {
|
if value >= 0 {
|
||||||
Ok(FeatureTagValue { tag: tag.into_owned(), value: value })
|
Ok(FeatureTagValue { tag: u_tag, value: value as u32 })
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
} else if let Ok(_) = input.try(|input| input.expect_ident_matching("on")) {
|
} else if let Ok(_) = input.try(|input| input.expect_ident_matching("on")) {
|
||||||
// on is an alias for '1'
|
// 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")) {
|
} else if let Ok(_) = input.try(|input| input.expect_ident_matching("off")) {
|
||||||
// off is an alias for '0'
|
// off is an alias for '0'
|
||||||
Ok(FeatureTagValue { tag: tag.into_owned(), value: 0 })
|
Ok(FeatureTagValue { tag: u_tag, value: 0 })
|
||||||
} else {
|
} else {
|
||||||
// empty value is an alias for '1'
|
// empty value is an alias for '1'
|
||||||
Ok(FeatureTagValue { tag:tag.into_owned(), value: 1 })
|
Ok(FeatureTagValue { tag: u_tag, value: 1 })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ doctest = false
|
||||||
testing = ["style/testing"]
|
testing = ["style/testing"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
byteorder = "1.0"
|
||||||
app_units = "0.4"
|
app_units = "0.4"
|
||||||
cssparser = "0.13"
|
cssparser = "0.13"
|
||||||
euclid = "0.11"
|
euclid = "0.11"
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#![feature(plugin, test)]
|
#![feature(plugin, test)]
|
||||||
|
|
||||||
extern crate app_units;
|
extern crate app_units;
|
||||||
|
extern crate byteorder;
|
||||||
extern crate cssparser;
|
extern crate cssparser;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
#[macro_use] extern crate html5ever;
|
#[macro_use] extern crate html5ever;
|
||||||
|
|
|
@ -10,38 +10,47 @@ use style_traits::ToCss;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn font_feature_settings_should_parse_properly() {
|
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 = parse_longhand!(font_feature_settings, "normal");
|
||||||
let normal_computed = computed_value::T::Normal;
|
let normal_computed = computed_value::T::Normal;
|
||||||
assert_eq!(normal, normal_computed);
|
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 = parse_longhand!(font_feature_settings, "\"abcd\" on");
|
||||||
let on_computed = computed_value::T::Tag(vec![
|
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);
|
assert_eq!(on, on_computed);
|
||||||
|
|
||||||
let off = parse_longhand!(font_feature_settings, "\"abcd\" off");
|
let off = parse_longhand!(font_feature_settings, "\"abcd\" off");
|
||||||
let off_computed = computed_value::T::Tag(vec![
|
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);
|
assert_eq!(off, off_computed);
|
||||||
|
|
||||||
let no_value = parse_longhand!(font_feature_settings, "\"abcd\"");
|
let no_value = parse_longhand!(font_feature_settings, "\"abcd\"");
|
||||||
let no_value_computed = computed_value::T::Tag(vec![
|
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);
|
assert_eq!(no_value, no_value_computed);
|
||||||
|
|
||||||
let pos_integer = parse_longhand!(font_feature_settings, "\"abcd\" 100");
|
let pos_integer = parse_longhand!(font_feature_settings, "\"abcd\" 100");
|
||||||
let pos_integer_computed = computed_value::T::Tag(vec![
|
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);
|
assert_eq!(pos_integer, pos_integer_computed);
|
||||||
|
|
||||||
let multiple = parse_longhand!(font_feature_settings, "\"abcd\" off, \"efgh\"");
|
let multiple = parse_longhand!(font_feature_settings, "\"abcd\" off, \"efgh\"");
|
||||||
let multiple_computed = computed_value::T::Tag(vec![
|
let multiple_computed = computed_value::T::Tag(vec![
|
||||||
FeatureTagValue { tag: String::from("abcd"), value: 0 },
|
FeatureTagValue { tag: abcd, value: 0 },
|
||||||
FeatureTagValue { tag: String::from("efgh"), value: 1 }
|
FeatureTagValue { tag: efgh, value: 1 }
|
||||||
]);
|
]);
|
||||||
assert_eq!(multiple, multiple_computed);
|
assert_eq!(multiple, multiple_computed);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue