diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index bb267122a918..92dbec55fa64 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -4219,8 +4219,6 @@ bool CanvasRenderingContext2D::SetFontInternalDisconnected( // In the OffscreenCanvas case we don't have the context necessary to call // GetFontStyleForServo(), as we do in the main-thread canvas context, so // instead we borrow ParseFontShorthandForMatching to parse the attribute. - StyleComputedFontStyleDescriptor style( - StyleComputedFontStyleDescriptor::Normal()); StyleFontFamilyList list; gfxFontStyle fontStyle; float size = 0.0f; diff --git a/gfx/thebes/SharedFontList.cpp b/gfx/thebes/SharedFontList.cpp index a4f0b4030abb..64aebf6d15c0 100644 --- a/gfx/thebes/SharedFontList.cpp +++ b/gfx/thebes/SharedFontList.cpp @@ -233,7 +233,7 @@ void Family::AddFaces(FontList* aList, const nsTArray& aFaces) { if (f.mWeight.Min().IsBold()) { slot |= kBoldMask; } - if (f.mStyle.Min().IsItalic() || f.mStyle.Min().IsOblique()) { + if (!f.mStyle.Min().IsNormal()) { slot |= kItalicMask; } if (slots[slot]) { @@ -604,7 +604,7 @@ void Family::SetFacePtrs(FontList* aList, nsTArray& aFaces) { if (f->mWeight.Min().IsBold()) { slot |= kBoldMask; } - if (f->mStyle.Min().IsItalic() || f->mStyle.Min().IsOblique()) { + if (!f->mStyle.Min().IsNormal()) { slot |= kItalicMask; } if (!slots[slot].IsNull()) { diff --git a/gfx/thebes/gfxFontEntry.cpp b/gfx/thebes/gfxFontEntry.cpp index b5040be84f16..b08ae368b145 100644 --- a/gfx/thebes/gfxFontEntry.cpp +++ b/gfx/thebes/gfxFontEntry.cpp @@ -1334,7 +1334,7 @@ void gfxFontEntry::GetVariationsForStyle(nsTArray& aResult, // The 'ital' axis is normally a binary toggle; intermediate values // can only be set using font-variation-settings. aResult.AppendElement(gfxFontVariation{HB_TAG('i', 't', 'a', 'l'), 1.0f}); - } else if (aStyle.style != StyleFontStyle::NORMAL && HasSlantVariation()) { + } else if (HasSlantVariation()) { // Figure out what slant angle we should try to match from the // requested style. float angle = aStyle.style.SlantAngle(); diff --git a/gfx/thebes/gfxFontEntry.h b/gfx/thebes/gfxFontEntry.h index 0fd73d037522..4ead2ff18dad 100644 --- a/gfx/thebes/gfxFontEntry.h +++ b/gfx/thebes/gfxFontEntry.h @@ -232,7 +232,9 @@ class gfxFontEntry { bool IsLocalUserFont() const { return mIsLocalUserFont; } bool IsFixedPitch() const { return mFixedPitch; } bool IsItalic() const { return SlantStyle().Min().IsItalic(); } - bool IsOblique() const { return SlantStyle().Min().IsOblique(); } + // IsOblique returns true if the oblique angle is non-zero; 'oblique 0deg' + // is synonymous with 'normal' and will return false here. + bool IsOblique() const { return !IsUpright() && !IsItalic(); } bool IsUpright() const { return SlantStyle().Min().IsNormal(); } inline bool SupportsItalic(); // defined below, because of RangeFlags use inline bool SupportsBold(); diff --git a/gfx/thebes/gfxFontUtils.h b/gfx/thebes/gfxFontUtils.h index ce11c6943d33..47d173d06234 100644 --- a/gfx/thebes/gfxFontUtils.h +++ b/gfx/thebes/gfxFontUtils.h @@ -1241,142 +1241,127 @@ static inline double StyleDistance(const mozilla::SlantStyleRange& aRange, const double kNegate = 200.0; if (aTargetStyle.IsNormal()) { - if (minStyle.IsOblique()) { - // to distinguish oblique 0deg from normal, we add 1.0 to the angle - const double minAngle = minStyle.ObliqueAngle(); - if (minAngle >= 0.0) { - return 1.0 + minAngle; - } - const mozilla::FontSlantStyle maxStyle = aRange.Max(); - const double maxAngle = maxStyle.ObliqueAngle(); - if (maxAngle >= 0.0) { - // [min,max] range includes 0.0, so just return our minimum - return 1.0; - } - // negative oblique is even worse than italic - return kNegate - maxAngle; + if (minStyle.IsItalic()) { + // italic is worse than any non-negative oblique; + // treat as a match in the wrong search direction + return kReverse; } - // must be italic, which is worse than any non-negative oblique; - // treat as a match in the wrong search direction - MOZ_ASSERT(minStyle.IsItalic()); - return kReverse; + const double minAngle = minStyle.ObliqueAngle(); + if (minAngle >= 0.0) { + return minAngle; + } + const mozilla::FontSlantStyle maxStyle = aRange.Max(); + const double maxAngle = maxStyle.ObliqueAngle(); + if (maxAngle >= 0.0) { + // [min,max] range includes 0.0, so it's a perfect match + return 0.0; + } + // negative oblique is even worse than italic + return kNegate - maxAngle; } const double kDefaultAngle = mozilla::FontSlantStyle::DEFAULT_OBLIQUE_DEGREES; if (aTargetStyle.IsItalic()) { - if (minStyle.IsOblique()) { - const double minAngle = minStyle.ObliqueAngle(); - if (minAngle >= kDefaultAngle) { - return 1.0 + (minAngle - kDefaultAngle); - } - const mozilla::FontSlantStyle maxStyle = aRange.Max(); - const double maxAngle = maxStyle.ObliqueAngle(); - if (maxAngle >= kDefaultAngle) { - return 1.0; - } - if (maxAngle > 0.0) { - // wrong direction but still > 0, add bias of 100 - return kReverse + (kDefaultAngle - maxAngle); - } - // negative oblique angle, add bias of 300 - return kReverse + kNegate + (kDefaultAngle - maxAngle); + MOZ_ASSERT(!minStyle.IsItalic()); // we checked for equality above + const mozilla::FontSlantStyle maxStyle = aRange.Max(); + if (maxStyle.IsItalic()) { + // Must be a font with an 'ital' axis, so consider this a match. + return 0.0; } - // normal is worse than oblique > 0, but better than oblique <= 0 - MOZ_ASSERT(minStyle.IsNormal()); - return kNegate; + const double minAngle = minStyle.ObliqueAngle(); + if (minAngle >= kDefaultAngle) { + // Add 1.0 to ensure italic vs non-italic never returns 0.0, even if the + // angle matches. + return minAngle - kDefaultAngle + 1.0; + } + const double maxAngle = maxStyle.ObliqueAngle(); + if (maxAngle >= kDefaultAngle) { + return 1.0; + } + if (maxAngle > 0.0) { + // wrong direction but still > 0, add bias of 100 + return kReverse + (kDefaultAngle - maxAngle); + } + // negative oblique angle, add bias of 300 + return kReverse + kNegate + (kDefaultAngle - maxAngle); } // target is oblique : four different cases depending on // the value of the , which determines the preferred direction // of search const double targetAngle = aTargetStyle.ObliqueAngle(); + const mozilla::FontSlantStyle maxStyle = aRange.Max(); if (targetAngle >= kDefaultAngle) { - if (minStyle.IsOblique()) { - const double minAngle = minStyle.ObliqueAngle(); - if (minAngle >= targetAngle) { - return minAngle - targetAngle; - } - const mozilla::FontSlantStyle maxStyle = aRange.Max(); - const double maxAngle = maxStyle.ObliqueAngle(); - if (maxAngle >= targetAngle) { - return 0.0; - } - if (maxAngle > 0.0) { - return kReverse + (targetAngle - maxAngle); - } - return kReverse + kNegate + (targetAngle - maxAngle); - } - if (minStyle.IsItalic()) { + if (minStyle.IsItalic() || maxStyle.IsItalic()) { return kReverse + kNegate; } - return kReverse + kNegate + 1.0; + const double minAngle = minStyle.ObliqueAngle(); + if (minAngle >= targetAngle) { + return minAngle - targetAngle; + } + const double maxAngle = maxStyle.ObliqueAngle(); + if (maxAngle >= targetAngle) { + return 0.0; + } + if (maxAngle > 0.0) { + return kReverse + (targetAngle - maxAngle); + } + return kReverse + kNegate + (targetAngle - maxAngle); } if (targetAngle <= -kDefaultAngle) { - if (minStyle.IsOblique()) { - const mozilla::FontSlantStyle maxStyle = aRange.Max(); - const double maxAngle = maxStyle.ObliqueAngle(); - if (maxAngle <= targetAngle) { - return targetAngle - maxAngle; - } - const double minAngle = minStyle.ObliqueAngle(); - if (minAngle <= targetAngle) { - return 0.0; - } - if (minAngle < 0.0) { - return kReverse + (minAngle - targetAngle); - } - return kReverse + kNegate + (minAngle - targetAngle); - } - if (minStyle.IsItalic()) { + if (minStyle.IsItalic() || maxStyle.IsItalic()) { return kReverse + kNegate; } - return kReverse + kNegate + 1.0; - } - - if (targetAngle >= 0.0) { - if (minStyle.IsOblique()) { - const double minAngle = minStyle.ObliqueAngle(); - if (minAngle > targetAngle) { - return kReverse + (minAngle - targetAngle); - } - const mozilla::FontSlantStyle maxStyle = aRange.Max(); - const double maxAngle = maxStyle.ObliqueAngle(); - if (maxAngle >= targetAngle) { - return 0.0; - } - if (maxAngle > 0.0) { - return targetAngle - maxAngle; - } - return kReverse + kNegate + (targetAngle - maxAngle); - } - if (minStyle.IsItalic()) { - return kReverse + kNegate - 2.0; - } - return kReverse + kNegate - 1.0; - } - - // last case: (targetAngle < 0.0 && targetAngle > kDefaultAngle) - if (minStyle.IsOblique()) { - const mozilla::FontSlantStyle maxStyle = aRange.Max(); const double maxAngle = maxStyle.ObliqueAngle(); - if (maxAngle < targetAngle) { - return kReverse + (targetAngle - maxAngle); + if (maxAngle <= targetAngle) { + return targetAngle - maxAngle; } const double minAngle = minStyle.ObliqueAngle(); if (minAngle <= targetAngle) { return 0.0; } if (minAngle < 0.0) { - return minAngle - targetAngle; + return kReverse + (minAngle - targetAngle); } return kReverse + kNegate + (minAngle - targetAngle); } - if (minStyle.IsItalic()) { - return kReverse + kNegate - 2.0; + + if (targetAngle >= 0.0) { + if (minStyle.IsItalic() || maxStyle.IsItalic()) { + return kReverse + kNegate - 1.0; + } + const double minAngle = minStyle.ObliqueAngle(); + if (minAngle > targetAngle) { + return kReverse + (minAngle - targetAngle); + } + const double maxAngle = maxStyle.ObliqueAngle(); + if (maxAngle >= targetAngle) { + return 0.0; + } + if (maxAngle > 0.0) { + return targetAngle - maxAngle; + } + return kReverse + kNegate + (targetAngle - maxAngle); } - return kReverse + kNegate - 1.0; + + // last case: (targetAngle < 0.0 && targetAngle > kDefaultAngle) + if (minStyle.IsItalic() || maxStyle.IsItalic()) { + return kReverse + kNegate - 1.0; + } + const double maxAngle = maxStyle.ObliqueAngle(); + if (maxAngle < targetAngle) { + return kReverse + (targetAngle - maxAngle); + } + const double minAngle = minStyle.ObliqueAngle(); + if (minAngle <= targetAngle) { + return 0.0; + } + if (minAngle < 0.0) { + return minAngle - targetAngle; + } + return kReverse + kNegate + (minAngle - targetAngle); } // stretch distance ==> [0,2000] diff --git a/layout/reftests/font-matching/descriptor-ranges.js b/layout/reftests/font-matching/descriptor-ranges.js index e59bd0d45c03..b33cad4e894b 100644 --- a/layout/reftests/font-matching/descriptor-ranges.js +++ b/layout/reftests/font-matching/descriptor-ranges.js @@ -62,8 +62,8 @@ testDescriptor("font-stretch", [ ]); testDescriptor("font-style", [ - { value: "normal", testDescriptors: ["normal", "oblique 0deg", "oblique 10deg 40deg", "oblique 20deg 30deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, - { value: "italic", testDescriptors: ["italic", "oblique 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 5deg 10deg", "oblique 5deg", "normal", "oblique 0deg", "oblique -60deg -30deg", "oblique -50deg -40deg" ] }, + { value: "normal", testDescriptors: ["normal", "oblique 10deg 40deg", "oblique 20deg 30deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, + { value: "italic", testDescriptors: ["italic", "oblique 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 5deg 10deg", "oblique 5deg", "normal", "oblique -60deg -30deg", "oblique -50deg -40deg" ] }, { value: "oblique 20deg", testDescriptors: ["oblique 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 10deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, { value: "oblique 21deg", testDescriptors: ["oblique 21deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 20deg", "oblique 10deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, { value: "oblique 10deg", testDescriptors: ["oblique 10deg", "oblique 5deg", "oblique 15deg 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, diff --git a/layout/style/FontFaceImpl.cpp b/layout/style/FontFaceImpl.cpp index baa4acdd06dc..e508a3f39212 100644 --- a/layout/style/FontFaceImpl.cpp +++ b/layout/style/FontFaceImpl.cpp @@ -595,9 +595,6 @@ bool FontFaceImpl::GetAttributes(gfxUserFontAttributes& aAttr) { if (Servo_FontFaceRule_GetFontStyle(data, &styleDesc)) { aAttr.mRangeFlags &= ~gfxFontEntry::RangeFlags::eAutoSlantStyle; switch (styleDesc.tag) { - case StyleComputedFontStyleDescriptor::Tag::Normal: - aAttr.mStyle = SlantStyleRange(FontSlantStyle::NORMAL); - break; case StyleComputedFontStyleDescriptor::Tag::Italic: aAttr.mStyle = SlantStyleRange(FontSlantStyle::ITALIC); break; diff --git a/layout/style/ServoStyleConstsInlines.h b/layout/style/ServoStyleConstsInlines.h index 0d5d2d76636b..7dee63b15976 100644 --- a/layout/style/ServoStyleConstsInlines.h +++ b/layout/style/ServoStyleConstsInlines.h @@ -1097,12 +1097,8 @@ inline bool StyleFontWeight::IsBold() const { return *this >= BOLD_THRESHOLD; } inline bool StyleFontStyle::IsItalic() const { return *this == ITALIC; } -inline bool StyleFontStyle::IsOblique() const { - return !IsItalic() && !IsNormal(); -} - inline float StyleFontStyle::ObliqueAngle() const { - MOZ_ASSERT(IsOblique()); + MOZ_ASSERT(!IsItalic()); return ToFloat(); } diff --git a/servo/components/style/font_face.rs b/servo/components/style/font_face.rs index fd52874da8a3..c328d5035faa 100644 --- a/servo/components/style/font_face.rs +++ b/servo/components/style/font_face.rs @@ -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> { + // 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( diff --git a/servo/components/style/values/computed/font.rs b/servo/components/style/values/computed/font.rs index 3219fb581596..1485895d93ae 100644 --- a/servo/components/style/values/computed/font.rs +++ b/servo/components/style/values/computed/font.rs @@ -1050,8 +1050,8 @@ impl ToComputedValue for specified::MathDepth { /// - Use a signed 8.8 fixed-point value (representable range -128.0..128) /// -/// Values of below -90 or above 90 not permitted, so we use out of -/// range values to represent normal | oblique +/// Values of 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; /// 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 ' -/// - 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 ` /// /// cbindgen:derive-lt /// cbindgen:derive-lte @@ -1086,13 +1085,14 @@ pub type FontStyleFixedPoint = FixedPoint; 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()), } } } diff --git a/servo/components/style/values/generics/font.rs b/servo/components/style/values/generics/font.rs index f080550818c5..55323b0066e9 100644 --- a/servo/components/style/values/generics/font.rs +++ b/servo/components/style/values/generics/font.rs @@ -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 { - #[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 FontStyle { + /// 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. diff --git a/servo/components/style/values/specified/font.rs b/servo/components/style/values/specified/font.rs index ee01506248ce..c255ed8199d6 100644 --- a/servo/components/style/values/specified/font.rs +++ b/servo/components/style/values/specified/font.rs @@ -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> { 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); diff --git a/servo/ports/geckolib/cbindgen.toml b/servo/ports/geckolib/cbindgen.toml index 0377c9916512..cda632c0a6a3 100644 --- a/servo/ports/geckolib/cbindgen.toml +++ b/servo/ports/geckolib/cbindgen.toml @@ -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}; diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 0c22216f4522..46c7eaa358c1 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -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()), }; diff --git a/testing/web-platform/meta/css/css-fonts/parsing/font-style-computed.html.ini b/testing/web-platform/meta/css/css-fonts/parsing/font-style-computed.html.ini index db981eec2903..161a55b89122 100644 --- a/testing/web-platform/meta/css/css-fonts/parsing/font-style-computed.html.ini +++ b/testing/web-platform/meta/css/css-fonts/parsing/font-style-computed.html.ini @@ -1,11 +1,3 @@ [font-style-computed.html] - expected: - if (os == "android") and fission: [OK, TIMEOUT] [Property font-style value 'oblique calc(30deg + (sign(20cqw - 10px) * 5deg))'] expected: FAIL - - [Property font-style value 'oblique 0deg'] - expected: FAIL - - [Property font-style value 'oblique calc(10deg - 10deg)'] - expected: FAIL diff --git a/testing/web-platform/meta/css/css-fonts/parsing/font-style-valid.html.ini b/testing/web-platform/meta/css/css-fonts/parsing/font-style-valid.html.ini index 479edee65ee2..308773737623 100644 --- a/testing/web-platform/meta/css/css-fonts/parsing/font-style-valid.html.ini +++ b/testing/web-platform/meta/css/css-fonts/parsing/font-style-valid.html.ini @@ -1,8 +1,3 @@ [font-style-valid.html] - expected: - if (os == "android") and fission: [OK, TIMEOUT] [e.style['font-style'\] = "oblique calc(30deg + (sign(2cqw - 10px) * 5deg))" should set the property value] expected: FAIL - - [e.style['font-style'\] = "oblique 0deg" should set the property value] - expected: FAIL diff --git a/testing/web-platform/meta/css/css-fonts/variations/font-style-parsing.html.ini b/testing/web-platform/meta/css/css-fonts/variations/font-style-parsing.html.ini deleted file mode 100644 index 2fc8c29558ad..000000000000 --- a/testing/web-platform/meta/css/css-fonts/variations/font-style-parsing.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[font-style-parsing.html] - [Font-style (computed): 'oblique' followed by zero degrees is valid] - expected: FAIL diff --git a/testing/web-platform/tests/css/css-fonts/font-face-style-normal.html b/testing/web-platform/tests/css/css-fonts/font-face-style-normal.html new file mode 100644 index 000000000000..440661b82bbb --- /dev/null +++ b/testing/web-platform/tests/css/css-fonts/font-face-style-normal.html @@ -0,0 +1,54 @@ + + + + +CSS Fonts: parsing 'normal' in the font-style descriptor + + + + + + + + + + + diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-style-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-style-computed.html index aa3df23ca81a..acb870cdc1f3 100644 --- a/testing/web-platform/tests/css/css-fonts/parsing/font-style-computed.html +++ b/testing/web-platform/tests/css/css-fonts/parsing/font-style-computed.html @@ -33,6 +33,8 @@ test_computed_value('font-style', 'oblique calc(10deg - 10deg)', 'normal'); test_computed_value('font-style', 'oblique 10deg'); test_computed_value('font-style', 'oblique -10deg'); +test_computed_value('font-style', 'oblique 14deg', 'oblique'); +test_computed_value('font-style', 'oblique -14deg'); test_computed_value('font-style', 'oblique -90deg'); test_computed_value('font-style', 'oblique 90deg'); test_computed_value('font-style', 'oblique 10grad', 'oblique 9deg'); diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-style-valid.html b/testing/web-platform/tests/css/css-fonts/parsing/font-style-valid.html index a2505b4ade21..95c5af3c4164 100644 --- a/testing/web-platform/tests/css/css-fonts/parsing/font-style-valid.html +++ b/testing/web-platform/tests/css/css-fonts/parsing/font-style-valid.html @@ -20,6 +20,8 @@ test_valid_value('font-style', 'oblique calc(10deg - 10deg)', 'oblique calc(0deg test_valid_value('font-style', 'oblique 10deg'); test_valid_value('font-style', 'oblique -10deg'); +test_valid_value('font-style', 'oblique 14deg', 'oblique'); +test_valid_value('font-style', 'oblique -14deg'); test_valid_value('font-style', 'oblique -90deg'); test_valid_value('font-style', 'oblique 90deg'); test_valid_value('font-style', 'oblique 10grad'); diff --git a/testing/web-platform/tests/css/css-fonts/variations/at-font-face-font-matching.html b/testing/web-platform/tests/css/css-fonts/variations/at-font-face-font-matching.html index e56334f2da77..ba18f9d5ab2e 100644 --- a/testing/web-platform/tests/css/css-fonts/variations/at-font-face-font-matching.html +++ b/testing/web-platform/tests/css/css-fonts/variations/at-font-face-font-matching.html @@ -126,7 +126,7 @@ } function createFontFaceRules(fontFaceFamily, descriptorName, expectedMatch, unexpectedMatch) { dynamicStyles.innerHTML = - "@font-face { font-family: " + fontFaceFamily + "; src: url('./resources/csstest-weights-100-kerned.ttf'); "+ descriptorName + ": " + expectedMatch + "; }" + + "@font-face { font-family: " + fontFaceFamily + "; src: url('./resources/csstest-weights-100-kerned.ttf'); " + descriptorName + ": " + expectedMatch + "; }" + "@font-face { font-family: " + fontFaceFamily + "; src: url('./resources/csstest-weights-200-kerned.ttf'); " + descriptorName + ": " + unexpectedMatch + "; }"; return Promise.all([ @@ -179,8 +179,8 @@ ]); testDescriptor("font-style", [ - { value: "normal", testDescriptors: ["normal", "oblique 0deg", "oblique 10deg 40deg", "oblique 20deg 30deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, - { value: "italic", testDescriptors: ["italic", "oblique 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 5deg 10deg", "oblique 5deg", "normal", "oblique 0deg", "oblique -60deg -30deg", "oblique -50deg -40deg" ] }, + { value: "normal", testDescriptors: ["normal", "oblique 10deg 40deg", "oblique 20deg 30deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, + { value: "italic", testDescriptors: ["italic", "oblique 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 5deg 10deg", "oblique 5deg", "normal", "oblique -60deg -30deg", "oblique -50deg -40deg" ] }, { value: "oblique 20deg", testDescriptors: ["oblique 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 10deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, { value: "oblique 21deg", testDescriptors: ["oblique 21deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 20deg", "oblique 10deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, { value: "oblique 10deg", testDescriptors: ["oblique 10deg", "oblique 5deg", "oblique 15deg 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] },