mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
style: Update font-weight property and descriptor to css-fonts-4.
Bug: 1454596 Reviewed-by: xidorn MozReview-Commit-ID: 27aS2UrgXjs
This commit is contained in:
parent
76a14d6a64
commit
bc1126ee8c
10 changed files with 199 additions and 141 deletions
|
@ -9,7 +9,7 @@
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use computed_values::{font_stretch, font_style, font_weight};
|
use computed_values::{font_stretch, font_style};
|
||||||
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
|
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
|
||||||
use cssparser::{CowRcStr, SourceLocation};
|
use cssparser::{CowRcStr, SourceLocation};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -27,7 +27,7 @@ use style_traits::{StyleParseErrorKind, ToCss};
|
||||||
use style_traits::values::SequenceWriter;
|
use style_traits::values::SequenceWriter;
|
||||||
use values::computed::font::FamilyName;
|
use values::computed::font::FamilyName;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings};
|
use values::specified::font::{AbsoluteFontWeight, SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings};
|
||||||
use values::specified::url::SpecifiedUrl;
|
use values::specified::url::SpecifiedUrl;
|
||||||
|
|
||||||
/// A source for a font-face rule.
|
/// A source for a font-face rule.
|
||||||
|
@ -92,38 +92,21 @@ pub enum FontDisplay {
|
||||||
Optional,
|
Optional,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A font-weight value for a @font-face rule.
|
/// The font-weight descriptor:
|
||||||
/// The font-weight CSS property specifies the weight or boldness of the font.
|
///
|
||||||
#[cfg(feature = "gecko")]
|
/// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-weight
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, ToCss)]
|
#[derive(Clone, Debug, PartialEq, ToCss)]
|
||||||
pub enum FontWeight {
|
pub struct FontWeight(pub AbsoluteFontWeight, pub Option<AbsoluteFontWeight>);
|
||||||
/// Numeric font weights for fonts that provide more than just normal and bold.
|
|
||||||
Weight(font_weight::T),
|
|
||||||
/// Normal font weight. Same as 400.
|
|
||||||
Normal,
|
|
||||||
/// Bold font weight. Same as 700.
|
|
||||||
Bold,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
impl Parse for FontWeight {
|
impl Parse for FontWeight {
|
||||||
fn parse<'i, 't>(
|
fn parse<'i, 't>(
|
||||||
_: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<FontWeight, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let result = input.try(|input| {
|
let first = AbsoluteFontWeight::parse(context, input)?;
|
||||||
let ident = input.expect_ident().map_err(|_| ())?;
|
let second =
|
||||||
match_ignore_ascii_case! { &ident,
|
input.try(|input| AbsoluteFontWeight::parse(context, input)).ok();
|
||||||
"normal" => Ok(FontWeight::Normal),
|
Ok(FontWeight(first, second))
|
||||||
"bold" => Ok(FontWeight::Bold),
|
|
||||||
_ => Err(())
|
|
||||||
}
|
|
||||||
});
|
|
||||||
result.or_else(|_| {
|
|
||||||
font_weight::T::from_int(input.expect_integer()?)
|
|
||||||
.map(FontWeight::Weight)
|
|
||||||
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//! Bindings for CSS Rule objects
|
//! Bindings for CSS Rule objects
|
||||||
|
|
||||||
use byteorder::{BigEndian, WriteBytesExt};
|
use byteorder::{BigEndian, WriteBytesExt};
|
||||||
use computed_values::{font_stretch, font_style, font_weight};
|
use computed_values::{font_stretch, font_style};
|
||||||
use counter_style::{self, CounterBound};
|
use counter_style::{self, CounterBound};
|
||||||
use cssparser::UnicodeRange;
|
use cssparser::UnicodeRange;
|
||||||
use font_face::{FontDisplay, FontWeight, Source};
|
use font_face::{FontDisplay, FontWeight, Source};
|
||||||
|
@ -15,6 +15,7 @@ use properties::longhands::font_language_override;
|
||||||
use std::str;
|
use std::str;
|
||||||
use values::computed::font::FamilyName;
|
use values::computed::font::FamilyName;
|
||||||
use values::generics::font::FontTag;
|
use values::generics::font::FontTag;
|
||||||
|
use values::specified::font::AbsoluteFontWeight;
|
||||||
use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings};
|
use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings};
|
||||||
|
|
||||||
impl<'a> ToNsCssValue for &'a FamilyName {
|
impl<'a> ToNsCssValue for &'a FamilyName {
|
||||||
|
@ -23,19 +24,9 @@ impl<'a> ToNsCssValue for &'a FamilyName {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToNsCssValue for font_weight::T {
|
impl<'a> ToNsCssValue for &'a AbsoluteFontWeight {
|
||||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||||
nscssvalue.set_font_weight(self.0)
|
nscssvalue.set_font_weight(self.compute().0)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ToNsCssValue for &'a FontWeight {
|
|
||||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
|
||||||
match *self {
|
|
||||||
FontWeight::Normal => nscssvalue.set_enum(structs::NS_FONT_WEIGHT_NORMAL as i32),
|
|
||||||
FontWeight::Bold => nscssvalue.set_enum(structs::NS_FONT_WEIGHT_BOLD as i32),
|
|
||||||
FontWeight::Weight(weight) => nscssvalue.set_font_weight(weight.0),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +68,28 @@ impl<'a> ToNsCssValue for &'a SpecifiedFontVariationSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ToNsCssValue for &'a FontWeight {
|
||||||
|
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||||
|
let FontWeight(ref first, ref second) = *self;
|
||||||
|
|
||||||
|
let second = match *second {
|
||||||
|
None => {
|
||||||
|
nscssvalue.set_from(first);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Some(ref second) => second,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut a = nsCSSValue::null();
|
||||||
|
let mut b = nsCSSValue::null();
|
||||||
|
|
||||||
|
a.set_from(first);
|
||||||
|
b.set_from(second);
|
||||||
|
|
||||||
|
nscssvalue.set_pair(&a, &b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ToNsCssValue for &'a font_language_override::SpecifiedValue {
|
impl<'a> ToNsCssValue for &'a font_language_override::SpecifiedValue {
|
||||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||||
match *self {
|
match *self {
|
||||||
|
|
|
@ -178,8 +178,8 @@ impl nsCSSValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set to a font weight
|
/// Set to a font weight
|
||||||
pub fn set_font_weight(&mut self, w: u16) {
|
pub fn set_font_weight(&mut self, w: f32) {
|
||||||
unsafe { bindings::Gecko_CSSValue_SetFontWeight(self, w as f32) }
|
unsafe { bindings::Gecko_CSSValue_SetFontWeight(self, w) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_int_internal(&mut self, value: i32, unit: nsCSSUnit) {
|
fn set_int_internal(&mut self, value: i32, unit: nsCSSUnit) {
|
||||||
|
|
|
@ -2607,9 +2607,7 @@ fn static_assert() {
|
||||||
|
|
||||||
pub fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T {
|
pub fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T {
|
||||||
let weight: f32 = unsafe { Gecko_FontWeight_ToFloat(self.gecko.mFont.weight) };
|
let weight: f32 = unsafe { Gecko_FontWeight_ToFloat(self.gecko.mFont.weight) };
|
||||||
debug_assert!(weight >= 0.0 &&
|
longhands::font_weight::computed_value::T(weight)
|
||||||
weight <= ::std::u16::MAX as f32);
|
|
||||||
longhands::font_weight::computed_value::T(weight as u16)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
${impl_simple_type_with_conversion("font_synthesis", "mFont.synthesis")}
|
${impl_simple_type_with_conversion("font_synthesis", "mFont.synthesis")}
|
||||||
|
|
|
@ -873,20 +873,6 @@ impl ToAnimatedZero for MaxLength {
|
||||||
fn to_animated_zero(&self) -> Result<Self, ()> { Err(()) }
|
fn to_animated_zero(&self) -> Result<Self, ()> { Err(()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <http://dev.w3.org/csswg/css-transitions/#animtype-font-weight>
|
|
||||||
impl Animate for FontWeight {
|
|
||||||
#[inline]
|
|
||||||
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
|
||||||
let a = self.0 as f64;
|
|
||||||
let b = other.0 as f64;
|
|
||||||
const NORMAL: f64 = 400.;
|
|
||||||
let (this_weight, other_weight) = procedure.weights();
|
|
||||||
let weight = (a - NORMAL) * this_weight + (b - NORMAL) * other_weight + NORMAL;
|
|
||||||
let weight = (weight.max(100.).min(900.) / 100.).round() * 100.;
|
|
||||||
Ok(FontWeight(weight as u16))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToAnimatedZero for FontWeight {
|
impl ToAnimatedZero for FontWeight {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||||
|
@ -897,8 +883,7 @@ impl ToAnimatedZero for FontWeight {
|
||||||
/// <https://drafts.csswg.org/css-fonts/#font-stretch-prop>
|
/// <https://drafts.csswg.org/css-fonts/#font-stretch-prop>
|
||||||
impl Animate for FontStretch {
|
impl Animate for FontStretch {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()>
|
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||||
{
|
|
||||||
let from = f64::from(*self);
|
let from = f64::from(*self);
|
||||||
let to = f64::from(*other);
|
let to = f64::from(*other);
|
||||||
let normal = f64::from(FontStretch::Normal);
|
let normal = f64::from(FontStretch::Normal);
|
||||||
|
|
|
@ -43,14 +43,16 @@ ${helpers.single_keyword_system("font-variant-caps",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
servo_restyle_damage="rebuild_and_reflow")}
|
servo_restyle_damage="rebuild_and_reflow")}
|
||||||
|
|
||||||
${helpers.predefined_type("font-weight",
|
${helpers.predefined_type(
|
||||||
"FontWeight",
|
"font-weight",
|
||||||
initial_value="computed::FontWeight::normal()",
|
"FontWeight",
|
||||||
initial_specified_value="specified::FontWeight::Normal",
|
initial_value="computed::FontWeight::normal()",
|
||||||
animation_value_type="ComputedValue",
|
initial_specified_value="specified::FontWeight::normal()",
|
||||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
animation_value_type="Number",
|
||||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight",
|
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||||
servo_restyle_damage="rebuild_and_reflow")}
|
spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight",
|
||||||
|
servo_restyle_damage="rebuild_and_reflow",
|
||||||
|
)}
|
||||||
|
|
||||||
${helpers.predefined_type("font-size",
|
${helpers.predefined_type("font-size",
|
||||||
"FontSize",
|
"FontSize",
|
||||||
|
|
|
@ -25,20 +25,35 @@ use values::animated::{ToAnimatedValue, ToAnimatedZero};
|
||||||
use values::computed::{Context, Integer, NonNegativeLength, Number, ToComputedValue};
|
use values::computed::{Context, Integer, NonNegativeLength, Number, ToComputedValue};
|
||||||
use values::generics::font::{FeatureTagValue, FontSettings};
|
use values::generics::font::{FeatureTagValue, FontSettings};
|
||||||
use values::generics::font::{KeywordInfo as GenericKeywordInfo, VariationValue};
|
use values::generics::font::{KeywordInfo as GenericKeywordInfo, VariationValue};
|
||||||
use values::specified::font as specified;
|
use values::specified::font::{self as specified, MIN_FONT_WEIGHT, MAX_FONT_WEIGHT};
|
||||||
use values::specified::length::{FontBaseSize, NoCalcLength};
|
use values::specified::length::{FontBaseSize, NoCalcLength};
|
||||||
|
|
||||||
pub use values::computed::Length as MozScriptMinSize;
|
pub use values::computed::Length as MozScriptMinSize;
|
||||||
pub use values::specified::font::{FontSynthesis, MozScriptSizeMultiplier, XLang, XTextZoom};
|
pub use values::specified::font::{FontSynthesis, MozScriptSizeMultiplier, XLang, XTextZoom};
|
||||||
|
|
||||||
/// As of CSS Fonts Module Level 3, only the following values are
|
/// A value for the font-weight property per:
|
||||||
/// valid: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
|
|
||||||
///
|
///
|
||||||
/// However, system fonts may provide other values. Pango
|
/// https://drafts.csswg.org/css-fonts-4/#propdef-font-weight
|
||||||
/// may provide 350, 380, and 1000 (on top of the existing values), for example.
|
///
|
||||||
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToCss)]
|
/// This is effectively just a `Number`.
|
||||||
|
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq,
|
||||||
|
ToCss)]
|
||||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||||
pub struct FontWeight(pub u16);
|
pub struct FontWeight(pub Number);
|
||||||
|
|
||||||
|
impl ToAnimatedValue for FontWeight {
|
||||||
|
type AnimatedValue = Number;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_animated_value(self) -> Self::AnimatedValue {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
||||||
|
FontWeight(animated.max(MIN_FONT_WEIGHT).min(MAX_FONT_WEIGHT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq,
|
#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq,
|
||||||
ToAnimatedZero, ToCss)]
|
ToAnimatedZero, ToCss)]
|
||||||
|
@ -57,21 +72,12 @@ pub type KeywordInfo = GenericKeywordInfo<NonNegativeLength>;
|
||||||
impl FontWeight {
|
impl FontWeight {
|
||||||
/// Value for normal
|
/// Value for normal
|
||||||
pub fn normal() -> Self {
|
pub fn normal() -> Self {
|
||||||
FontWeight(400)
|
FontWeight(400.)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Value for bold
|
/// Value for bold
|
||||||
pub fn bold() -> Self {
|
pub fn bold() -> Self {
|
||||||
FontWeight(700)
|
FontWeight(700.)
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert from an integer to Weight
|
|
||||||
pub fn from_int(n: i32) -> Result<Self, ()> {
|
|
||||||
if n >= 100 && n <= 900 && n % 100 == 0 {
|
|
||||||
Ok(FontWeight(n as u16))
|
|
||||||
} else {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert from an Gecko weight
|
/// Convert from an Gecko weight
|
||||||
|
@ -80,33 +86,39 @@ impl FontWeight {
|
||||||
// we allow a wider range of weights than is parseable
|
// we allow a wider range of weights than is parseable
|
||||||
// because system fonts may provide custom values
|
// because system fonts may provide custom values
|
||||||
let weight = unsafe { bindings::Gecko_FontWeight_ToFloat(weight) };
|
let weight = unsafe { bindings::Gecko_FontWeight_ToFloat(weight) };
|
||||||
FontWeight(weight as u16)
|
FontWeight(weight)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Weither this weight is bold
|
/// Weither this weight is bold
|
||||||
pub fn is_bold(&self) -> bool {
|
pub fn is_bold(&self) -> bool {
|
||||||
self.0 > 500
|
self.0 > 500.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the bolder weight
|
/// Return the bolder weight.
|
||||||
|
///
|
||||||
|
/// See the table in:
|
||||||
|
/// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values
|
||||||
pub fn bolder(self) -> Self {
|
pub fn bolder(self) -> Self {
|
||||||
if self.0 < 400 {
|
if self.0 < 350. {
|
||||||
FontWeight(400)
|
FontWeight(400.)
|
||||||
} else if self.0 < 600 {
|
} else if self.0 < 550. {
|
||||||
FontWeight(700)
|
FontWeight(700.)
|
||||||
} else {
|
} else {
|
||||||
FontWeight(900)
|
FontWeight(self.0.max(900.))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the lighter weight
|
/// Return the lighter weight.
|
||||||
|
///
|
||||||
|
/// See the table in:
|
||||||
|
/// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values
|
||||||
pub fn lighter(self) -> Self {
|
pub fn lighter(self) -> Self {
|
||||||
if self.0 < 600 {
|
if self.0 < 550. {
|
||||||
FontWeight(100)
|
FontWeight(self.0.min(100.))
|
||||||
} else if self.0 < 800 {
|
} else if self.0 < 750. {
|
||||||
FontWeight(400)
|
FontWeight(400.)
|
||||||
} else {
|
} else {
|
||||||
FontWeight(700)
|
FontWeight(700.)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,29 +27,43 @@ use values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX};
|
||||||
const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8;
|
const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8;
|
||||||
const DEFAULT_SCRIPT_SIZE_MULTIPLIER: f64 = 0.71;
|
const DEFAULT_SCRIPT_SIZE_MULTIPLIER: f64 = 0.71;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss)]
|
/// The minimum font-weight value per:
|
||||||
/// A specified font-weight value
|
///
|
||||||
|
/// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values
|
||||||
|
pub const MIN_FONT_WEIGHT: f32 = 1.;
|
||||||
|
|
||||||
|
/// The maximum font-weight value per:
|
||||||
|
///
|
||||||
|
/// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values
|
||||||
|
pub const MAX_FONT_WEIGHT: f32 = 1000.;
|
||||||
|
|
||||||
|
/// A specified font-weight value.
|
||||||
|
///
|
||||||
|
/// https://drafts.csswg.org/css-fonts-4/#propdef-font-weight
|
||||||
|
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||||
pub enum FontWeight {
|
pub enum FontWeight {
|
||||||
/// Normal variant
|
/// `<font-weight-absolute>`
|
||||||
Normal,
|
Absolute(AbsoluteFontWeight),
|
||||||
/// Bold variant
|
|
||||||
Bold,
|
|
||||||
/// Bolder variant
|
/// Bolder variant
|
||||||
Bolder,
|
Bolder,
|
||||||
/// Lighter variant
|
/// Lighter variant
|
||||||
Lighter,
|
Lighter,
|
||||||
/// Computed weight variant
|
/// System font variant.
|
||||||
Weight(computed::FontWeight),
|
|
||||||
/// System font varaint
|
|
||||||
System(SystemFont),
|
System(SystemFont),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontWeight {
|
impl FontWeight {
|
||||||
|
/// `normal`
|
||||||
|
#[inline]
|
||||||
|
pub fn normal() -> Self {
|
||||||
|
FontWeight::Absolute(AbsoluteFontWeight::Normal)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a specified FontWeight from a gecko keyword
|
/// Get a specified FontWeight from a gecko keyword
|
||||||
pub fn from_gecko_keyword(kw: u32) -> Self {
|
pub fn from_gecko_keyword(kw: u32) -> Self {
|
||||||
computed::FontWeight::from_int(kw as i32)
|
debug_assert!(kw % 100 == 0);
|
||||||
.map(FontWeight::Weight)
|
debug_assert!(kw as f32 <= MAX_FONT_WEIGHT);
|
||||||
.expect("Found unexpected value in style struct for font-weight property")
|
FontWeight::Absolute(AbsoluteFontWeight::Weight(Number::new(kw as f32)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a specified FontWeight from a SystemFont
|
/// Get a specified FontWeight from a SystemFont
|
||||||
|
@ -69,27 +83,17 @@ impl FontWeight {
|
||||||
|
|
||||||
impl Parse for FontWeight {
|
impl Parse for FontWeight {
|
||||||
fn parse<'i, 't>(
|
fn parse<'i, 't>(
|
||||||
_: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<FontWeight, ParseError<'i>> {
|
) -> Result<FontWeight, ParseError<'i>> {
|
||||||
let result = match *input.next()? {
|
if let Ok(absolute) = input.try(|input| AbsoluteFontWeight::parse(context, input)) {
|
||||||
Token::Ident(ref ident) => {
|
return Ok(FontWeight::Absolute(absolute));
|
||||||
match_ignore_ascii_case! { ident,
|
}
|
||||||
"normal" => Ok(FontWeight::Normal),
|
|
||||||
"bold" => Ok(FontWeight::Bold),
|
|
||||||
"bolder" => Ok(FontWeight::Bolder),
|
|
||||||
"lighter" => Ok(FontWeight::Lighter),
|
|
||||||
_ => Err(()),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Token::Number {
|
|
||||||
int_value: Some(value),
|
|
||||||
..
|
|
||||||
} => computed::FontWeight::from_int(value).map(FontWeight::Weight),
|
|
||||||
_ => Err(()),
|
|
||||||
};
|
|
||||||
|
|
||||||
result.map_err(|_| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
Ok(try_match_ident_ignore_ascii_case! { input,
|
||||||
|
"bolder" => FontWeight::Bolder,
|
||||||
|
"lighter" => FontWeight::Lighter,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,9 +103,7 @@ impl ToComputedValue for FontWeight {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||||
match *self {
|
match *self {
|
||||||
FontWeight::Weight(weight) => weight,
|
FontWeight::Absolute(ref abs) => abs.compute(),
|
||||||
FontWeight::Normal => computed::FontWeight::normal(),
|
|
||||||
FontWeight::Bold => computed::FontWeight::bold(),
|
|
||||||
FontWeight::Bolder => context
|
FontWeight::Bolder => context
|
||||||
.builder
|
.builder
|
||||||
.get_parent_font()
|
.get_parent_font()
|
||||||
|
@ -126,7 +128,64 @@ impl ToComputedValue for FontWeight {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_computed_value(computed: &computed::FontWeight) -> Self {
|
fn from_computed_value(computed: &computed::FontWeight) -> Self {
|
||||||
FontWeight::Weight(*computed)
|
FontWeight::Absolute(AbsoluteFontWeight::Weight(
|
||||||
|
Number::from_computed_value(&computed.0)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An absolute font-weight value for a @font-face rule.
|
||||||
|
///
|
||||||
|
/// https://drafts.csswg.org/css-fonts-4/#font-weight-absolute-values
|
||||||
|
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||||
|
pub enum AbsoluteFontWeight {
|
||||||
|
/// A `<number>`, with the additional constraints specified in:
|
||||||
|
///
|
||||||
|
/// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values
|
||||||
|
Weight(Number),
|
||||||
|
/// Normal font weight. Same as 400.
|
||||||
|
Normal,
|
||||||
|
/// Bold font weight. Same as 700.
|
||||||
|
Bold,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AbsoluteFontWeight {
|
||||||
|
/// Returns the computed value for this absolute font weight.
|
||||||
|
pub fn compute(&self) -> computed::FontWeight {
|
||||||
|
match *self {
|
||||||
|
AbsoluteFontWeight::Weight(weight) => {
|
||||||
|
computed::FontWeight(
|
||||||
|
weight.get().max(MIN_FONT_WEIGHT).min(MAX_FONT_WEIGHT)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
AbsoluteFontWeight::Normal => computed::FontWeight::normal(),
|
||||||
|
AbsoluteFontWeight::Bold => computed::FontWeight::bold(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for AbsoluteFontWeight {
|
||||||
|
fn parse<'i, 't>(
|
||||||
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
if let Ok(number) = input.try(|input| Number::parse(context, input)) {
|
||||||
|
// We could add another AllowedNumericType value, but it doesn't
|
||||||
|
// seem worth it just for a single property with such a weird range,
|
||||||
|
// so we do the clamping here manually.
|
||||||
|
if !number.was_calc() &&
|
||||||
|
(number.get() < MIN_FONT_WEIGHT || number.get() > MAX_FONT_WEIGHT) {
|
||||||
|
return Err(input.new_custom_error(
|
||||||
|
StyleParseErrorKind::UnspecifiedError
|
||||||
|
))
|
||||||
|
}
|
||||||
|
return Ok(AbsoluteFontWeight::Weight(number))
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(try_match_ident_ignore_ascii_case! { input,
|
||||||
|
"normal" => AbsoluteFontWeight::Normal,
|
||||||
|
"bold" => AbsoluteFontWeight::Bold,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,14 @@ impl Number {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether this number came from a `calc()` expression.
|
||||||
|
#[inline]
|
||||||
|
pub fn was_calc(&self) -> bool {
|
||||||
|
self.calc_clamping_mode.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the numeric value, clamped if needed.
|
/// Returns the numeric value, clamped if needed.
|
||||||
|
#[inline]
|
||||||
pub fn get(&self) -> f32 {
|
pub fn get(&self) -> f32 {
|
||||||
self.calc_clamping_mode
|
self.calc_clamping_mode
|
||||||
.map_or(self.value, |mode| mode.clamp(self.value))
|
.map_or(self.value, |mode| mode.clamp(self.value))
|
||||||
|
|
|
@ -5395,10 +5395,9 @@ pub extern "C" fn Servo_ParseFontShorthandForMatching(
|
||||||
font_stretch::SpecifiedValue::Keyword(ref kw) => kw,
|
font_stretch::SpecifiedValue::Keyword(ref kw) => kw,
|
||||||
font_stretch::SpecifiedValue::System(_) => return false,
|
font_stretch::SpecifiedValue::System(_) => return false,
|
||||||
});
|
});
|
||||||
|
|
||||||
match font.font_weight {
|
match font.font_weight {
|
||||||
FontWeight::Weight(w) => weight.set_from(w),
|
FontWeight::Absolute(w) => weight.set_font_weight(w.compute().0),
|
||||||
FontWeight::Normal => weight.set_enum(structs::NS_FONT_WEIGHT_NORMAL as i32),
|
|
||||||
FontWeight::Bold => weight.set_enum(structs::NS_FONT_WEIGHT_BOLD as i32),
|
|
||||||
// Resolve relative font weights against the initial of font-weight
|
// Resolve relative font weights against the initial of font-weight
|
||||||
// (normal, which is equivalent to 400).
|
// (normal, which is equivalent to 400).
|
||||||
FontWeight::Bolder => weight.set_enum(structs::NS_FONT_WEIGHT_BOLD as i32),
|
FontWeight::Bolder => weight.set_enum(structs::NS_FONT_WEIGHT_BOLD as i32),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue