Bug 1349417 - Part 4: stylo: System font support for font-weight; r?xidorn
MozReview-Commit-ID: 1L55bqGnpCs
--- a/servo/components/style/properties/data.py
+++ b/servo/components/style/properties/data.py
@@ -10,17 +10,17 @@ PHYSICAL_SIZES = ["width", "height"]
LOGICAL_SIZES = ["block-size", "inline-size"]
# bool is True when logical
ALL_SIDES = [(side, False) for side in PHYSICAL_SIDES] + [(side, True) for side in LOGICAL_SIDES]
ALL_SIZES = [(size, False) for size in PHYSICAL_SIZES] + [(size, True) for size in LOGICAL_SIZES]
SYSTEM_FONT_LONGHANDS = """font_family font_size font_style
font_variant_caps font_stretch font_kerning
- font_variant_position""".split()
+ font_variant_position font_weight""".split()
def maybe_moz_logical_alias(product, side, prop):
if product == "gecko" and side[1]:
axis, dir = side[0].split("-")
if axis == "inline":
return prop % dir
return None
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -1364,20 +1364,17 @@ fn static_assert() {
}
pub fn set_font_weight(&mut self, v: longhands::font_weight::computed_value::T) {
self.gecko.mFont.weight = v as u16;
}
${impl_simple_copy('font_weight', 'mFont.weight')}
pub fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T {
- debug_assert!(self.gecko.mFont.weight >= 100);
- debug_assert!(self.gecko.mFont.weight <= 900);
- debug_assert!(self.gecko.mFont.weight % 10 == 0);
- unsafe { transmute(self.gecko.mFont.weight) }
+ unsafe { longhands::font_weight::computed_value::T::from_gecko_weight(self.gecko.mFont.weight) }
}
pub fn set_font_synthesis(&mut self, v: longhands::font_synthesis::computed_value::T) {
use gecko_bindings::structs::{NS_FONT_SYNTHESIS_WEIGHT, NS_FONT_SYNTHESIS_STYLE};
self.gecko.mFont.synthesis = 0;
if v.weight {
self.gecko.mFont.synthesis |= NS_FONT_SYNTHESIS_WEIGHT as u8;
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -305,44 +305,48 @@
custom_consts=font_variant_caps_custom_consts,
animation_type="none")}
<%helpers:longhand name="font-weight" need_clone="True" animation_type="normal"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight">
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
+ use properties::longhands::system_font::SystemFont;
no_viewport_percentage!(SpecifiedValue);
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue {
Normal,
Bold,
Bolder,
Lighter,
% for weight in range(100, 901, 100):
Weight${weight},
% endfor
+ 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::Bold => dest.write_str("bold"),
SpecifiedValue::Bolder => dest.write_str("bolder"),
SpecifiedValue::Lighter => dest.write_str("lighter"),
% for weight in range(100, 901, 100):
SpecifiedValue::Weight${weight} => dest.write_str("${weight}"),
% endfor
+ SpecifiedValue::System(_) => Ok(())
}
}
}
+
/// normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
input.try(|input| {
match_ignore_ascii_case! { &try!(input.expect_ident()),
"normal" => Ok(SpecifiedValue::Normal),
"bold" => Ok(SpecifiedValue::Bold),
"bolder" => Ok(SpecifiedValue::Bolder),
"lighter" => Ok(SpecifiedValue::Lighter),
@@ -364,27 +368,41 @@
}
pub fn from_gecko_keyword(kw: u32) -> Self {
Self::from_int(kw as i32).expect("Found unexpected value in style
struct for font-weight property")
}
}
+ 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
+ }
+ }
+ }
+
/// Used in @font-face, where relative keywords are not allowed.
impl Parse for computed_value::T {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
match parse(context, input)? {
% for weight in range(100, 901, 100):
SpecifiedValue::Weight${weight} => Ok(computed_value::T::Weight${weight}),
% endfor
SpecifiedValue::Normal => Ok(computed_value::T::Weight400),
SpecifiedValue::Bold => Ok(computed_value::T::Weight700),
SpecifiedValue::Bolder |
- SpecifiedValue::Lighter => Err(())
+ SpecifiedValue::Lighter => Err(()),
+ SpecifiedValue::System(..) => unreachable!(),
}
}
}
pub mod computed_value {
use std::fmt;
#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
@@ -398,16 +416,25 @@
#[inline]
pub fn is_bold(self) -> bool {
match self {
T::Weight900 | T::Weight800 |
T::Weight700 | T::Weight600 => true,
_ => false
}
}
+
+ /// Obtain a Servo computed value from a Gecko computed font-weight
+ pub unsafe fn from_gecko_weight(weight: u16) -> Self {
+ use std::mem::transmute;
+ debug_assert!(weight >= 100);
+ debug_assert!(weight <= 900);
+ debug_assert!(weight % 10 == 0);
+ transmute(weight)
+ }
}
}
impl ToCss for computed_value::T {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
% for weight in range(100, 901, 100):
computed_value::T::Weight${weight} => dest.write_str("${weight}"),
% endfor
@@ -452,16 +479,21 @@
computed_value::T::Weight300 => computed_value::T::Weight100,
computed_value::T::Weight400 => computed_value::T::Weight100,
computed_value::T::Weight500 => computed_value::T::Weight100,
computed_value::T::Weight600 => computed_value::T::Weight400,
computed_value::T::Weight700 => computed_value::T::Weight400,
computed_value::T::Weight800 => computed_value::T::Weight700,
computed_value::T::Weight900 => computed_value::T::Weight700,
},
+ SpecifiedValue::System(_) => {
+ <%self:nongecko_unreachable>
+ context.style.cached_system_font.as_ref().unwrap().font_weight.clone()
+ </%self:nongecko_unreachable>
+ }
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
% for weight in range(100, 901, 100):
computed_value::T::Weight${weight} => SpecifiedValue::Weight${weight},
@@ -1929,19 +1961,23 @@ macro_rules! exclusive_value {
}
let family = system.fontlist.mFontlist.iter().map(|font| {
use properties::longhands::font_family::computed_value::*;
FontFamily::FamilyName(FamilyName {
name: (&*font.mName).into(),
quoted: true
})
}).collect::<Vec<_>>();
+ let weight = unsafe {
+ longhands::font_weight::computed_value::T::from_gecko_weight(system.weight)
+ };
let ret = ComputedSystemFont {
font_family: longhands::font_family::computed_value::T(family),
font_size: Au(system.size),
+ font_weight: weight,
% for kwprop in kw_font_props:
${kwprop}: longhands::${kwprop}::computed_value::T::from_gecko_keyword(
system.${to_camel_case_lower(kwprop.replace('font_', ''))} as u32
),
% endfor
system_font: *self,
};
unsafe { bindings::Gecko_nsFont_Destroy(&mut system); }
--- a/servo/components/style/properties/shorthand/font.mako.rs
+++ b/servo/components/style/properties/shorthand/font.mako.rs
@@ -41,17 +41,17 @@
let mut stretch = None;
let size;
% if product == "gecko":
if let Ok(sys) = input.try(SystemFont::parse) {
return Ok(Longhands {
% for name in SYSTEM_FONT_LONGHANDS:
${name}: ${name}::SpecifiedValue::system_font(sys),
% endfor
- % for name in gecko_sub_properties + "weight variant_caps stretch".split():
+ % for name in gecko_sub_properties + "variant_caps stretch".split():
% if "font_" + name not in SYSTEM_FONT_LONGHANDS:
font_${name}: font_${name}::get_initial_specified_value(),
% endif
% endfor
line_height: line_height::get_initial_specified_value(),
})
}
% endif