Bug 1945637 - Remove the separate 'normal' value of font-style types, as it is a synonym for 'oblique 0deg'; always serialize 'oblique 0deg' as 'normal'. r=firefox-style-system-reviewers,emilio

Differential Revision: https://phabricator.services.mozilla.com/D236733
This commit is contained in:
Jonathan Kew
2025-02-06 19:38:57 +00:00
parent 9e30d4a3f1
commit a0e8acbf5c
21 changed files with 216 additions and 195 deletions

View File

@@ -379,7 +379,6 @@ impl FontStretchRange {
#[derive(Clone, Debug, PartialEq, ToShmem)]
#[allow(missing_docs)]
pub enum FontStyle {
Normal,
Italic,
Oblique(Angle, Angle),
}
@@ -389,7 +388,6 @@ pub enum FontStyle {
#[repr(u8)]
#[allow(missing_docs)]
pub enum ComputedFontStyleDescriptor {
Normal,
Italic,
Oblique(f32, f32),
}
@@ -399,9 +397,14 @@ impl Parse for FontStyle {
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
// We parse 'normal' explicitly here to distinguish it from 'oblique 0deg',
// because we must not accept a following angle.
if input.try_parse(|i| i.expect_ident_matching("normal")).is_ok() {
return Ok(FontStyle::Oblique(Angle::zero(), Angle::zero()));
}
let style = SpecifiedFontStyle::parse(context, input)?;
Ok(match style {
GenericFontStyle::Normal => FontStyle::Normal,
GenericFontStyle::Italic => FontStyle::Italic,
GenericFontStyle::Oblique(angle) => {
let second_angle = input
@@ -420,9 +423,13 @@ impl ToCss for FontStyle {
W: fmt::Write,
{
match *self {
FontStyle::Normal => dest.write_str("normal"),
FontStyle::Italic => dest.write_str("italic"),
FontStyle::Oblique(ref first, ref second) => {
// Not first.is_zero() because we don't want to serialize
// `oblique calc(0deg)` as `normal`.
if *first == Angle::zero() && first == second {
return dest.write_str("normal");
}
dest.write_str("oblique")?;
if *first != SpecifiedFontStyle::default_angle() || first != second {
dest.write_char(' ')?;
@@ -442,7 +449,6 @@ impl FontStyle {
/// Returns a computed font-style descriptor.
pub fn compute(&self) -> ComputedFontStyleDescriptor {
match *self {
FontStyle::Normal => ComputedFontStyleDescriptor::Normal,
FontStyle::Italic => ComputedFontStyleDescriptor::Italic,
FontStyle::Oblique(ref first, ref second) => {
let (min, max) = sort_range(

View File

@@ -1050,8 +1050,8 @@ impl ToComputedValue for specified::MathDepth {
/// - Use a signed 8.8 fixed-point value (representable range -128.0..128)
///
/// Values of <angle> below -90 or above 90 not permitted, so we use out of
/// range values to represent normal | oblique
/// Values of <angle> below -90 or above 90 are not permitted, so we use an out
/// of range value to represent `italic`.
pub const FONT_STYLE_FRACTION_BITS: u16 = 8;
/// This is an alias which is useful mostly as a cbindgen / C++ inference
@@ -1060,10 +1060,9 @@ pub type FontStyleFixedPoint = FixedPoint<i16, FONT_STYLE_FRACTION_BITS>;
/// The computed value of `font-style`.
///
/// - Define out of range values min value (-128.0) as meaning 'normal'
/// - Define max value (127.99609375) as 'italic'
/// - Other values represent 'oblique <angle>'
/// - Note that 'oblique 0deg' is distinct from 'normal' (should it be?)
/// - Define angle of zero degrees as `normal`
/// - Define out-of-range value 100 degrees as `italic`
/// - Other values represent `oblique <angle>`
///
/// cbindgen:derive-lt
/// cbindgen:derive-lte
@@ -1086,13 +1085,14 @@ pub type FontStyleFixedPoint = FixedPoint<i16, FONT_STYLE_FRACTION_BITS>;
pub struct FontStyle(FontStyleFixedPoint);
impl FontStyle {
/// The normal keyword.
/// The `normal` keyword, equal to `oblique` with angle zero.
pub const NORMAL: FontStyle = FontStyle(FontStyleFixedPoint {
value: 100 << FONT_STYLE_FRACTION_BITS,
value: 0 << FONT_STYLE_FRACTION_BITS,
});
/// The italic keyword.
pub const ITALIC: FontStyle = FontStyle(FontStyleFixedPoint {
value: 101 << FONT_STYLE_FRACTION_BITS,
value: 100 << FONT_STYLE_FRACTION_BITS,
});
/// The default angle for `font-style: oblique`.
@@ -1121,7 +1121,6 @@ impl FontStyle {
/// Returns the oblique angle for this style.
pub fn oblique_degrees(&self) -> f32 {
debug_assert_ne!(*self, Self::NORMAL);
debug_assert_ne!(*self, Self::ITALIC);
self.0.to_float()
}
@@ -1138,12 +1137,12 @@ impl ToCss for FontStyle {
if *self == Self::ITALIC {
return dest.write_str("italic");
}
if *self == Self::OBLIQUE {
return dest.write_str("oblique");
dest.write_str("oblique")?;
if *self != Self::OBLIQUE {
// It's not the default oblique amount, so append the angle in degrees.
dest.write_char(' ')?;
Angle::from_degrees(self.oblique_degrees()).to_css(dest)?;
}
dest.write_str("oblique ")?;
let angle = Angle::from_degrees(self.oblique_degrees());
angle.to_css(dest)?;
Ok(())
}
}
@@ -1153,12 +1152,6 @@ impl ToAnimatedValue for FontStyle {
#[inline]
fn to_animated_value(self, _: &crate::values::animated::Context) -> Self::AnimatedValue {
if self == Self::NORMAL {
// This allows us to animate between normal and oblique values. Per spec,
// https://drafts.csswg.org/css-fonts-4/#font-style-prop:
// Animation type: by computed value type; 'normal' animates as 'oblique 0deg'
return generics::FontStyle::Oblique(Angle::from_degrees(0.0));
}
if self == Self::ITALIC {
return generics::FontStyle::Italic;
}
@@ -1168,16 +1161,8 @@ impl ToAnimatedValue for FontStyle {
#[inline]
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
match animated {
generics::FontStyle::Normal => Self::NORMAL,
generics::FontStyle::Italic => Self::ITALIC,
generics::FontStyle::Oblique(ref angle) => {
if angle.degrees() == 0.0 {
// Reverse the conversion done in to_animated_value()
Self::NORMAL
} else {
Self::oblique(angle.degrees())
}
},
generics::FontStyle::Oblique(ref angle) => Self::oblique(angle.degrees()),
}
}
}

View File

@@ -6,7 +6,7 @@
use crate::parser::{Parse, ParserContext};
use crate::values::animated::ToAnimatedZero;
use crate::One;
use crate::{One, Zero};
use byteorder::{BigEndian, ReadBytesExt};
use cssparser::Parser;
use std::fmt::{self, Write};
@@ -208,13 +208,18 @@ impl Parse for FontTag {
ToResolvedValue,
ToShmem,
)]
#[value_info(other_values = "normal")]
pub enum FontStyle<Angle> {
#[animation(error)]
Normal,
#[animation(error)]
Italic,
// Note that 'oblique 0deg' represents 'normal', and will serialize as such.
#[value_info(starts_with_keyword)]
Oblique(Angle),
#[animation(error)]
Italic,
}
impl<Angle: Zero> FontStyle<Angle> {
/// Return the 'normal' value, which is represented as 'oblique 0deg'.
pub fn normal() -> Self { Self::Oblique(Angle::zero()) }
}
/// A generic value for the `font-size-adjust` property.

View File

@@ -257,13 +257,18 @@ impl ToCss for SpecifiedFontStyle {
W: Write,
{
match *self {
generics::FontStyle::Normal => dest.write_str("normal"),
generics::FontStyle::Italic => dest.write_str("italic"),
generics::FontStyle::Oblique(ref angle) => {
dest.write_str("oblique")?;
if *angle != Self::default_angle() {
dest.write_char(' ')?;
angle.to_css(dest)?;
// Not angle.is_zero() because we don't want to serialize
// `oblique calc(0deg)` as `normal`.
if *angle == Angle::zero() {
dest.write_str("normal")?;
} else {
dest.write_str("oblique")?;
if *angle != Self::default_angle() {
dest.write_char(' ')?;
angle.to_css(dest)?;
}
}
Ok(())
},
@@ -277,7 +282,7 @@ impl Parse for SpecifiedFontStyle {
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Ok(try_match_ident_ignore_ascii_case! { input,
"normal" => generics::FontStyle::Normal,
"normal" => generics::FontStyle::normal(),
"italic" => generics::FontStyle::Italic,
"oblique" => {
let angle = input.try_parse(|input| Self::parse_angle(context, input))
@@ -294,16 +299,12 @@ impl ToComputedValue for SpecifiedFontStyle {
fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
match *self {
Self::Normal => computed::FontStyle::NORMAL,
Self::Italic => computed::FontStyle::ITALIC,
Self::Oblique(ref angle) => computed::FontStyle::oblique(angle.degrees()),
}
}
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
if *computed == computed::FontStyle::NORMAL {
return Self::Normal;
}
if *computed == computed::FontStyle::ITALIC {
return Self::Italic;
}
@@ -375,7 +376,7 @@ impl FontStyle {
/// Return the `normal` value.
#[inline]
pub fn normal() -> Self {
FontStyle::Specified(generics::FontStyle::Normal)
FontStyle::Specified(generics::FontStyle::normal())
}
system_font_methods!(FontStyle, font_style);

View File

@@ -1025,8 +1025,7 @@ renaming_overrides_prefixing = true
SERVO_FIXED_POINT_HELPERS(StyleFontStyle, int16_t, StyleFONT_STYLE_FRACTION_BITS);
bool IsNormal() const { return *this == NORMAL; }
inline bool IsItalic() const;
inline bool IsOblique() const;
inline float ObliqueAngle() const; // Only for use when IsOblique() is true
inline float ObliqueAngle() const; // Not for use when IsItalic() is true
inline float SlantAngle() const; // Returns angle for any font-style, including
// normal/italic as well as explicit oblique
"""
@@ -1076,6 +1075,12 @@ renaming_overrides_prefixing = true
float ToMilliseconds() const { return seconds * 1000.0f; }
"""
"ComputedFontStyleDescriptor" = """
inline static StyleComputedFontStyleDescriptor Normal() {
return StyleComputedFontStyleDescriptor::Oblique(0, 0);
}
"""
"FontFaceSourceTechFlags" = """
inline static StyleFontFaceSourceTechFlags Empty() {
return StyleFontFaceSourceTechFlags{0};

View File

@@ -5429,11 +5429,11 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(
longhands::font_size::SpecifiedValue::from_html_size(value as u8)
},
FontStyle => {
style::values::specified::FontStyle::Specified(if value == structs::NS_FONT_STYLE_ITALIC {
specified::FontStyle::Specified(if value == structs::NS_FONT_STYLE_ITALIC {
FontStyle::Italic
} else {
debug_assert_eq!(value, structs::NS_FONT_STYLE_NORMAL);
FontStyle::Normal
FontStyle::normal()
})
},
FontWeight => longhands::font_weight::SpecifiedValue::from_gecko_keyword(value),
@@ -8555,7 +8555,6 @@ pub unsafe extern "C" fn Servo_ParseFontShorthandForMatching(
};
*style = match *specified_font_style {
GenericFontStyle::Normal => FontStyle::NORMAL,
GenericFontStyle::Italic => FontStyle::ITALIC,
GenericFontStyle::Oblique(ref angle) => FontStyle::oblique(angle.degrees()),
};