mirror of
https://github.com/servo/servo.git
synced 2025-08-11 08:25:32 +01:00
style: Refactor font-feature-settings and font-variation-settings.
This fixes all known issues with serialization and parsing of these two properties, and in particular calc handling and such: https://bugzilla.mozilla.org/show_bug.cgi?id=1434692 https://bugzilla.mozilla.org/show_bug.cgi?id=1434724 Also does a fair amount of cleanup and all that, which was needed.
This commit is contained in:
parent
09398d42af
commit
3b34d734e6
11 changed files with 270 additions and 261 deletions
|
@ -21,8 +21,8 @@ use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
|||
use values::CustomIdent;
|
||||
use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue};
|
||||
use values::computed::font::{SingleFontFamily, FontFamilyList, FamilyName};
|
||||
use values::generics::font::{FontSettings, FontSettingTagFloat};
|
||||
use values::specified::{AllowQuirks, LengthOrPercentage, NoCalcLength, Number};
|
||||
use values::generics::font::{FontSettings, FeatureTagValue, VariationValue};
|
||||
use values::specified::{AllowQuirks, Integer, LengthOrPercentage, NoCalcLength, Number};
|
||||
use values::specified::length::{AU_PER_PT, AU_PER_PX, FontBaseSize};
|
||||
|
||||
const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8;
|
||||
|
@ -164,8 +164,8 @@ impl From<LengthOrPercentage> for FontSize {
|
|||
}
|
||||
}
|
||||
|
||||
/// Specifies a prioritized list of font family names or generic family names.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
/// Specifies a prioritized list of font family names or generic family names
|
||||
pub enum FontFamily {
|
||||
/// List of `font-family`
|
||||
Values(FontFamilyList),
|
||||
|
@ -1709,13 +1709,15 @@ impl Parse for FontVariantNumeric {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
|
||||
#[derive(Clone, Debug, PartialEq, ToCss)]
|
||||
/// Define initial settings that apply when the font defined
|
||||
/// by an @font-face rule is rendered.
|
||||
/// This property provides low-level control over OpenType or TrueType font variations.
|
||||
pub type SpecifiedFontFeatureSettings = FontSettings<FeatureTagValue<Integer>>;
|
||||
|
||||
/// Define initial settings that apply when the font defined by an @font-face
|
||||
/// rule is rendered.
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
pub enum FontFeatureSettings {
|
||||
/// Value of `FontSettings`
|
||||
Value(computed::FontFeatureSettings),
|
||||
Value(SpecifiedFontFeatureSettings),
|
||||
/// System font
|
||||
System(SystemFont)
|
||||
}
|
||||
|
@ -1724,7 +1726,7 @@ impl FontFeatureSettings {
|
|||
#[inline]
|
||||
/// Get default value of `font-feature-settings` as normal
|
||||
pub fn normal() -> FontFeatureSettings {
|
||||
FontFeatureSettings::Value(FontSettings::Normal)
|
||||
FontFeatureSettings::Value(FontSettings::normal())
|
||||
}
|
||||
|
||||
/// Get `font-feature-settings` with system font
|
||||
|
@ -1745,12 +1747,12 @@ impl FontFeatureSettings {
|
|||
impl ToComputedValue for FontFeatureSettings {
|
||||
type ComputedValue = computed::FontFeatureSettings;
|
||||
|
||||
fn to_computed_value(&self, _context: &Context) -> computed::FontFeatureSettings {
|
||||
fn to_computed_value(&self, context: &Context) -> computed::FontFeatureSettings {
|
||||
match *self {
|
||||
FontFeatureSettings::Value(ref v) => v.clone(),
|
||||
FontFeatureSettings::Value(ref v) => v.to_computed_value(context),
|
||||
FontFeatureSettings::System(_) => {
|
||||
#[cfg(feature = "gecko")] {
|
||||
_context.cached_system_font.as_ref().unwrap().font_feature_settings.clone()
|
||||
context.cached_system_font.as_ref().unwrap().font_feature_settings.clone()
|
||||
}
|
||||
#[cfg(feature = "servo")] {
|
||||
unreachable!()
|
||||
|
@ -1760,7 +1762,7 @@ impl ToComputedValue for FontFeatureSettings {
|
|||
}
|
||||
|
||||
fn from_computed_value(other: &computed::FontFeatureSettings) -> Self {
|
||||
FontFeatureSettings::Value(other.clone())
|
||||
FontFeatureSettings::Value(ToComputedValue::from_computed_value(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1770,7 +1772,7 @@ impl Parse for FontFeatureSettings {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
) -> Result<FontFeatureSettings, ParseError<'i>> {
|
||||
computed::FontFeatureSettings::parse(context, input).map(FontFeatureSettings::Value)
|
||||
SpecifiedFontFeatureSettings::parse(context, input).map(FontFeatureSettings::Value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2006,9 +2008,51 @@ impl ToCss for FontTag {
|
|||
}
|
||||
}
|
||||
|
||||
/// This property provides low-level control over OpenType or TrueType font
|
||||
/// variations.
|
||||
pub type FontVariationSettings = FontSettings<VariationValue<Number>>;
|
||||
|
||||
fn parse_one_feature_value<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Integer, ParseError<'i>> {
|
||||
if let Ok(integer) = input.try(|i| Integer::parse_non_negative(context, i)) {
|
||||
return Ok(integer)
|
||||
}
|
||||
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
"on" => Ok(Integer::new(1)),
|
||||
"off" => Ok(Integer::new(0)),
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for FeatureTagValue<Integer> {
|
||||
/// https://drafts.csswg.org/css-fonts-4/#feature-tag-value
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let tag = FontTag::parse(context, input)?;
|
||||
let value = input.try(|i| parse_one_feature_value(context, i))
|
||||
.unwrap_or_else(|_| Integer::new(1));
|
||||
|
||||
Ok(Self { tag, value })
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for VariationValue<Number> {
|
||||
/// This is the `<string> <number>` part of the font-variation-settings
|
||||
/// syntax.
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let tag = FontTag::parse(context, input)?;
|
||||
let value = Number::parse(context, input)?;
|
||||
Ok(Self { tag, value })
|
||||
}
|
||||
}
|
||||
|
||||
/// This property provides low-level control over OpenType or TrueType font variations.
|
||||
pub type FontVariantSettings = FontSettings<FontSettingTagFloat>;
|
||||
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
|
||||
/// text-zoom. Enable if true, disable if false
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
use Namespace;
|
||||
use context::QuirksMode;
|
||||
use cssparser::{Parser, Token, serialize_identifier};
|
||||
use num_traits::One;
|
||||
use parser::{ParserContext, Parse};
|
||||
use self::url::SpecifiedUrl;
|
||||
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||
|
@ -33,7 +34,7 @@ pub use self::background::{BackgroundRepeat, BackgroundSize};
|
|||
pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth};
|
||||
pub use self::border::{BorderImageSideWidth, BorderRadius, BorderSideWidth, BorderSpacing};
|
||||
pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontWeight, FontVariantAlternates};
|
||||
pub use self::font::{FontFamily, FontLanguageOverride, FontVariantSettings, FontVariantEastAsian};
|
||||
pub use self::font::{FontFamily, FontLanguageOverride, FontVariationSettings, FontVariantEastAsian};
|
||||
pub use self::font::{FontVariantLigatures, FontVariantNumeric, FontFeatureSettings};
|
||||
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XTextZoom, XLang};
|
||||
pub use self::box_::{AnimationIterationCount, AnimationName, Display, OverscrollBehavior, Contain};
|
||||
|
@ -382,12 +383,28 @@ impl ToComputedValue for Opacity {
|
|||
/// An specified `<integer>`, optionally coming from a `calc()` expression.
|
||||
///
|
||||
/// <https://drafts.csswg.org/css-values/#integers>
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd)]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd)]
|
||||
pub struct Integer {
|
||||
value: CSSInteger,
|
||||
was_calc: bool,
|
||||
}
|
||||
|
||||
impl One for Integer {
|
||||
#[inline]
|
||||
fn one() -> Self {
|
||||
Self::new(1)
|
||||
}
|
||||
}
|
||||
|
||||
// This is not great, because it loses calc-ness, but it's necessary for One.
|
||||
impl ::std::ops::Mul<Integer> for Integer {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, other: Self) -> Self {
|
||||
Self::new(self.value * other.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Integer {
|
||||
/// Trivially constructs a new `Integer` value.
|
||||
pub fn new(val: CSSInteger) -> Self {
|
||||
|
@ -435,7 +452,7 @@ impl Integer {
|
|||
pub fn parse_with_minimum<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
min: i32
|
||||
min: i32,
|
||||
) -> Result<Integer, ParseError<'i>> {
|
||||
match Integer::parse(context, input) {
|
||||
// FIXME(emilio): The spec asks us to avoid rejecting it at parse
|
||||
|
@ -498,10 +515,11 @@ impl ToCss for Integer {
|
|||
pub type IntegerOrAuto = Either<Integer, Auto>;
|
||||
|
||||
impl IntegerOrAuto {
|
||||
#[allow(missing_docs)]
|
||||
pub fn parse_positive<'i, 't>(context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>)
|
||||
-> Result<IntegerOrAuto, ParseError<'i>> {
|
||||
/// Parse `auto` or a positive integer.
|
||||
pub fn parse_positive<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<IntegerOrAuto, ParseError<'i>> {
|
||||
match IntegerOrAuto::parse(context, input) {
|
||||
Ok(Either::First(integer)) if integer.value() <= 0 => {
|
||||
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue