зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #17430 - Store font-weight as integer directly (from upsuper:font-weight-int); r=nox
It doesn't make much sense to store `font-weight` as separate enums, especially given that we would need to support (somehow) arbitrary font weight value when we implement CSS Fonts Level 4. This PR refactors the `font-weight` a bit to make it store as `u16` directly. Source-Repo: https://github.com/servo/servo Source-Revision: f11a922760a08ffb956607d9ab447f8f2a319a25 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 2c8f317216c5c66b2ced1f308efe14ff61fb3add
This commit is contained in:
Родитель
0c16f513c9
Коммит
220e6d47b6
|
@ -46,7 +46,7 @@ impl FontTemplateDescriptor {
|
|||
// A value higher than all weights.
|
||||
return 1000
|
||||
}
|
||||
((self.weight as i16) - (other.weight as i16)).abs() as u32
|
||||
((self.weight.0 as i16) - (other.weight.0 as i16)).abs() as u32
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ impl FontHandleMethods for FontHandle {
|
|||
unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC as c_long != 0 }
|
||||
}
|
||||
fn boldness(&self) -> font_weight::T {
|
||||
let default_weight = font_weight::T::Weight400;
|
||||
let default_weight = font_weight::T::normal();
|
||||
if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD as c_long == 0 } {
|
||||
default_weight
|
||||
} else {
|
||||
|
@ -136,18 +136,13 @@ impl FontHandleMethods for FontHandle {
|
|||
let os2 = FT_Get_Sfnt_Table(self.face, FT_Sfnt_Tag::FT_SFNT_OS2) as *mut TT_OS2;
|
||||
let valid = !os2.is_null() && (*os2).version != 0xffff;
|
||||
if valid {
|
||||
let weight =(*os2).usWeightClass;
|
||||
match weight {
|
||||
1 | 100...199 => font_weight::T::Weight100,
|
||||
2 | 200...299 => font_weight::T::Weight200,
|
||||
3 | 300...399 => font_weight::T::Weight300,
|
||||
4 | 400...499 => font_weight::T::Weight400,
|
||||
5 | 500...599 => font_weight::T::Weight500,
|
||||
6 | 600...699 => font_weight::T::Weight600,
|
||||
7 | 700...799 => font_weight::T::Weight700,
|
||||
8 | 800...899 => font_weight::T::Weight800,
|
||||
9 | 900...999 => font_weight::T::Weight900,
|
||||
_ => default_weight
|
||||
let weight =(*os2).usWeightClass as i32;
|
||||
if weight < 10 {
|
||||
font_weight::T::from_int(weight * 100).unwrap()
|
||||
} else if weight >= 100 && weight < 1000 {
|
||||
font_weight::T::from_int(weight / 100 * 100).unwrap()
|
||||
} else {
|
||||
default_weight
|
||||
}
|
||||
} else {
|
||||
default_weight
|
||||
|
|
|
@ -217,17 +217,7 @@ impl FontHandleMethods for FontHandle {
|
|||
} else {
|
||||
4.0 + normalized * 5.0 // [4.0, 9.0]
|
||||
}; // [1.0, 9.0], centered on 4.0
|
||||
match normalized.round() as u32 {
|
||||
1 => font_weight::T::Weight100,
|
||||
2 => font_weight::T::Weight200,
|
||||
3 => font_weight::T::Weight300,
|
||||
4 => font_weight::T::Weight400,
|
||||
5 => font_weight::T::Weight500,
|
||||
6 => font_weight::T::Weight600,
|
||||
7 => font_weight::T::Weight700,
|
||||
8 => font_weight::T::Weight800,
|
||||
_ => font_weight::T::Weight900,
|
||||
}
|
||||
font_weight::T::from_int(normalized.round() as i32 * 100).unwrap()
|
||||
}
|
||||
|
||||
fn stretchiness(&self) -> font_stretch::T {
|
||||
|
|
|
@ -155,18 +155,8 @@ impl FontInfo {
|
|||
},
|
||||
};
|
||||
|
||||
let weight = match min(9, max(1, weight_val / 100)) {
|
||||
1 => font_weight::T::Weight100,
|
||||
2 => font_weight::T::Weight200,
|
||||
3 => font_weight::T::Weight300,
|
||||
4 => font_weight::T::Weight400,
|
||||
5 => font_weight::T::Weight500,
|
||||
6 => font_weight::T::Weight600,
|
||||
7 => font_weight::T::Weight700,
|
||||
8 => font_weight::T::Weight800,
|
||||
9 => font_weight::T::Weight900,
|
||||
_ => return Err(()),
|
||||
};
|
||||
let weight = font_weight::T::
|
||||
from_int(min(9, max(1, weight_val as i32 / 100)) * 100).unwrap();
|
||||
|
||||
let stretch = match min(9, max(1, width_val)) {
|
||||
1 => font_stretch::T::ultra_condensed,
|
||||
|
@ -198,21 +188,21 @@ impl FontInfo {
|
|||
|
||||
fn new_from_font(font: &Font) -> Result<FontInfo, ()> {
|
||||
let style = font.style();
|
||||
let weight = match font.weight() {
|
||||
FontWeight::Thin => font_weight::T::Weight100,
|
||||
FontWeight::ExtraLight => font_weight::T::Weight200,
|
||||
FontWeight::Light => font_weight::T::Weight300,
|
||||
let weight = font_weight::T(match font.weight() {
|
||||
FontWeight::Thin => 100,
|
||||
FontWeight::ExtraLight => 200,
|
||||
FontWeight::Light => 300,
|
||||
// slightly grayer gray
|
||||
FontWeight::SemiLight => font_weight::T::Weight300,
|
||||
FontWeight::Regular => font_weight::T::Weight400,
|
||||
FontWeight::Medium => font_weight::T::Weight500,
|
||||
FontWeight::SemiBold => font_weight::T::Weight600,
|
||||
FontWeight::Bold => font_weight::T::Weight700,
|
||||
FontWeight::ExtraBold => font_weight::T::Weight800,
|
||||
FontWeight::Black => font_weight::T::Weight900,
|
||||
FontWeight::SemiLight => 300,
|
||||
FontWeight::Regular => 400,
|
||||
FontWeight::Medium => 500,
|
||||
FontWeight::SemiBold => 600,
|
||||
FontWeight::Bold => 700,
|
||||
FontWeight::ExtraBold => 800,
|
||||
FontWeight::Black => 900,
|
||||
// slightly blacker black
|
||||
FontWeight::ExtraBlack => font_weight::T::Weight900,
|
||||
};
|
||||
FontWeight::ExtraBlack => 900,
|
||||
});
|
||||
let stretch = match font.stretch() {
|
||||
FontStretch::Undefined => font_stretch::T::normal,
|
||||
FontStretch::UltraCondensed => font_stretch::T::ultra_condensed,
|
||||
|
|
|
@ -109,29 +109,13 @@ impl Parse for FontWeight {
|
|||
}
|
||||
});
|
||||
result.or_else(|_| {
|
||||
FontWeight::from_int(input.expect_integer()?)
|
||||
font_weight::T::from_int(input.expect_integer()?)
|
||||
.map(FontWeight::Weight)
|
||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl FontWeight {
|
||||
fn from_int(kw: i32) -> Result<Self, ()> {
|
||||
match kw {
|
||||
100 => Ok(FontWeight::Weight(font_weight::T::Weight100)),
|
||||
200 => Ok(FontWeight::Weight(font_weight::T::Weight200)),
|
||||
300 => Ok(FontWeight::Weight(font_weight::T::Weight300)),
|
||||
400 => Ok(FontWeight::Weight(font_weight::T::Weight400)),
|
||||
500 => Ok(FontWeight::Weight(font_weight::T::Weight500)),
|
||||
600 => Ok(FontWeight::Weight(font_weight::T::Weight600)),
|
||||
700 => Ok(FontWeight::Weight(font_weight::T::Weight700)),
|
||||
800 => Ok(FontWeight::Weight(font_weight::T::Weight800)),
|
||||
900 => Ok(FontWeight::Weight(font_weight::T::Weight900)),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Parse the block inside a `@font-face` rule.
|
||||
///
|
||||
/// Note that the prelude parsing code lives in the `stylesheets` module.
|
||||
|
|
|
@ -31,7 +31,7 @@ impl ToNsCssValue for FamilyName {
|
|||
|
||||
impl ToNsCssValue for font_weight::T {
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
nscssvalue.set_integer(self as i32)
|
||||
nscssvalue.set_integer(self.0 as i32)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ impl ToNsCssValue for FontWeight {
|
|||
nscssvalue.set_enum(structs::NS_STYLE_FONT_WEIGHT_NORMAL as i32),
|
||||
FontWeight::Bold =>
|
||||
nscssvalue.set_enum(structs::NS_STYLE_FONT_WEIGHT_BOLD as i32),
|
||||
FontWeight::Weight(weight) => nscssvalue.set_integer(weight as i32),
|
||||
FontWeight::Weight(weight) => nscssvalue.set_integer(weight.0 as i32),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1906,7 +1906,7 @@ fn static_assert() {
|
|||
}
|
||||
|
||||
pub fn set_font_weight(&mut self, v: longhands::font_weight::computed_value::T) {
|
||||
self.gecko.mFont.weight = v as u16;
|
||||
self.gecko.mFont.weight = v.0;
|
||||
}
|
||||
${impl_simple_copy('font_weight', 'mFont.weight')}
|
||||
|
||||
|
|
|
@ -1415,38 +1415,21 @@ impl Animatable for MaxLength {
|
|||
impl Animatable for FontWeight {
|
||||
#[inline]
|
||||
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||
let a = (*self as u32) as f64;
|
||||
let b = (*other as u32) as f64;
|
||||
let a = self.0 as f64;
|
||||
let b = other.0 as f64;
|
||||
const NORMAL: f64 = 400.;
|
||||
let weight = (a - NORMAL) * self_portion + (b - NORMAL) * other_portion + NORMAL;
|
||||
Ok(if weight < 150. {
|
||||
FontWeight::Weight100
|
||||
} else if weight < 250. {
|
||||
FontWeight::Weight200
|
||||
} else if weight < 350. {
|
||||
FontWeight::Weight300
|
||||
} else if weight < 450. {
|
||||
FontWeight::Weight400
|
||||
} else if weight < 550. {
|
||||
FontWeight::Weight500
|
||||
} else if weight < 650. {
|
||||
FontWeight::Weight600
|
||||
} else if weight < 750. {
|
||||
FontWeight::Weight700
|
||||
} else if weight < 850. {
|
||||
FontWeight::Weight800
|
||||
} else {
|
||||
FontWeight::Weight900
|
||||
})
|
||||
let weight = (weight.min(100.).max(900.) / 100.).round() * 100.;
|
||||
Ok(FontWeight(weight as u16))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_zero_value(&self) -> Result<Self, ()> { Ok(FontWeight::Weight400) }
|
||||
fn get_zero_value(&self) -> Result<Self, ()> { Ok(FontWeight::normal()) }
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
let a = (*self as u32) as f64;
|
||||
let b = (*other as u32) as f64;
|
||||
let a = self.0 as f64;
|
||||
let b = other.0 as f64;
|
||||
a.compute_distance(&b)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -422,9 +422,7 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
Bold,
|
||||
Bolder,
|
||||
Lighter,
|
||||
% for weight in range(100, 901, 100):
|
||||
Weight${weight},
|
||||
% endfor
|
||||
Weight(computed_value::T),
|
||||
System(SystemFont),
|
||||
}
|
||||
|
||||
|
@ -435,16 +433,14 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
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::Weight(weight) => weight.to_css(dest),
|
||||
SpecifiedValue::System(_) => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
|
||||
pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<SpecifiedValue, ParseError<'i>> {
|
||||
let result = input.try(|input| {
|
||||
let ident = input.expect_ident().map_err(|_| ())?;
|
||||
|
@ -456,25 +452,13 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
_ => Err(())
|
||||
}
|
||||
});
|
||||
result.or_else(|_| {
|
||||
SpecifiedValue::from_int(input.expect_integer()?)
|
||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
||||
})
|
||||
result.or_else(|_| computed_value::T::parse(context, input).map(SpecifiedValue::Weight))
|
||||
}
|
||||
|
||||
impl SpecifiedValue {
|
||||
pub fn from_int(kw: i32) -> Result<Self, ()> {
|
||||
match kw {
|
||||
% for weight in range(100, 901, 100):
|
||||
${weight} => Ok(SpecifiedValue::Weight${weight}),
|
||||
% endfor
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
computed_value::T::from_int(kw as i32).map(SpecifiedValue::Weight)
|
||||
.expect("Found unexpected value in style struct for font-weight property")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,64 +475,79 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
}
|
||||
}
|
||||
|
||||
/// Used in @font-face, where relative keywords are not allowed.
|
||||
impl Parse for computed_value::T {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
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(StyleParseError::UnspecifiedError.into()),
|
||||
SpecifiedValue::System(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod computed_value {
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
|
||||
/// As of CSS Fonts Module Level 3, only the following values are
|
||||
/// valid: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, ToCss)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
|
||||
#[repr(u16)]
|
||||
pub enum T {
|
||||
% for weight in range(100, 901, 100):
|
||||
Weight${weight} = ${weight},
|
||||
% endfor
|
||||
}
|
||||
pub struct T(pub u16);
|
||||
|
||||
impl T {
|
||||
#[inline]
|
||||
pub fn is_bold(self) -> bool {
|
||||
match self {
|
||||
T::Weight900 | T::Weight800 |
|
||||
T::Weight700 | T::Weight600 => true,
|
||||
_ => false
|
||||
/// Value for normal
|
||||
pub fn normal() -> Self {
|
||||
T(400)
|
||||
}
|
||||
|
||||
/// Value for bold
|
||||
pub fn bold() -> Self {
|
||||
T(700)
|
||||
}
|
||||
|
||||
/// Convert from an integer to Weight
|
||||
pub fn from_int(n: i32) -> Result<Self, ()> {
|
||||
if n >= 100 && n <= 900 && n % 100 == 0 {
|
||||
Ok(T(n as u16))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Obtain a Servo computed value from a Gecko computed font-weight
|
||||
/// Convert from an Gecko weight
|
||||
pub fn from_gecko_weight(weight: u16) -> Self {
|
||||
match weight {
|
||||
% for weight in range(100, 901, 100):
|
||||
${weight} => T::Weight${weight},
|
||||
% endfor
|
||||
_ => panic!("from_gecko_weight: called with invalid weight")
|
||||
Self::from_int(weight as i32)
|
||||
.expect("from_gecko_weight: called with invalid weight")
|
||||
}
|
||||
|
||||
/// Weither this weight is bold
|
||||
pub fn is_bold(&self) -> bool {
|
||||
self.0 > 500
|
||||
}
|
||||
|
||||
/// Return the bolder weight
|
||||
pub fn bolder(self) -> Self {
|
||||
if self.0 < 400 {
|
||||
T(400)
|
||||
} else if self.0 < 600 {
|
||||
T(700)
|
||||
} else {
|
||||
T(900)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the lighter weight
|
||||
pub fn lighter(self) -> Self {
|
||||
if self.0 < 600 {
|
||||
T(100)
|
||||
} else if self.0 < 800 {
|
||||
T(400)
|
||||
} else {
|
||||
T(700)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
impl Parse for computed_value::T {
|
||||
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
Self::from_int(input.expect_integer()?)
|
||||
.map_err(|_| StyleParseError::UnspecifiedError.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_initial_value() -> computed_value::T {
|
||||
computed_value::T::Weight400 // normal
|
||||
computed_value::T::normal()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -562,33 +561,13 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
#[inline]
|
||||
fn to_computed_value(&self, context: &Context) -> computed_value::T {
|
||||
match *self {
|
||||
% for weight in range(100, 901, 100):
|
||||
SpecifiedValue::Weight${weight} => computed_value::T::Weight${weight},
|
||||
% endfor
|
||||
SpecifiedValue::Normal => computed_value::T::Weight400,
|
||||
SpecifiedValue::Bold => computed_value::T::Weight700,
|
||||
SpecifiedValue::Bolder => match context.inherited_style().get_font().clone_font_weight() {
|
||||
computed_value::T::Weight100 => computed_value::T::Weight400,
|
||||
computed_value::T::Weight200 => computed_value::T::Weight400,
|
||||
computed_value::T::Weight300 => computed_value::T::Weight400,
|
||||
computed_value::T::Weight400 => computed_value::T::Weight700,
|
||||
computed_value::T::Weight500 => computed_value::T::Weight700,
|
||||
computed_value::T::Weight600 => computed_value::T::Weight900,
|
||||
computed_value::T::Weight700 => computed_value::T::Weight900,
|
||||
computed_value::T::Weight800 => computed_value::T::Weight900,
|
||||
computed_value::T::Weight900 => computed_value::T::Weight900,
|
||||
},
|
||||
SpecifiedValue::Lighter => match context.inherited_style().get_font().clone_font_weight() {
|
||||
computed_value::T::Weight100 => computed_value::T::Weight100,
|
||||
computed_value::T::Weight200 => computed_value::T::Weight100,
|
||||
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::Weight(weight) => weight,
|
||||
SpecifiedValue::Normal => computed_value::T::normal(),
|
||||
SpecifiedValue::Bold => computed_value::T::bold(),
|
||||
SpecifiedValue::Bolder =>
|
||||
context.inherited_style().get_font().clone_font_weight().bolder(),
|
||||
SpecifiedValue::Lighter =>
|
||||
context.inherited_style().get_font().clone_font_weight().lighter(),
|
||||
SpecifiedValue::System(_) => {
|
||||
<%self:nongecko_unreachable>
|
||||
context.cached_system_font.as_ref().unwrap().font_weight.clone()
|
||||
|
@ -599,11 +578,7 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
|
||||
#[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},
|
||||
% endfor
|
||||
}
|
||||
SpecifiedValue::Weight(*computed)
|
||||
}
|
||||
}
|
||||
</%helpers:longhand>
|
||||
|
|
|
@ -1673,7 +1673,7 @@ pub mod style_structs {
|
|||
// Corresponds to the fields in
|
||||
// `gfx::font_template::FontTemplateDescriptor`.
|
||||
let mut hasher: FnvHasher = Default::default();
|
||||
hasher.write_u16(self.font_weight as u16);
|
||||
hasher.write_u16(self.font_weight.0);
|
||||
self.font_stretch.hash(&mut hasher);
|
||||
self.font_family.hash(&mut hasher);
|
||||
self.hash = hasher.finish()
|
||||
|
|
|
@ -184,7 +184,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
|||
let mut font_style = self.style.mutate_font();
|
||||
// Sadly we don't have a nice name for the computed value
|
||||
// of "font-weight: normal".
|
||||
font_style.set_font_weight(font_weight::Weight400);
|
||||
font_style.set_font_weight(font_weight::normal());
|
||||
font_style.set_font_style(font_style::normal);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче