--- a/servo/components/style/font_face.rs
+++ b/servo/components/style/font_face.rs
@@ -21,18 +21,18 @@ use str::CssStringWriter;
use style_traits::{Comma, CssWriter, OneOrMoreSeparated, ParseError};
use style_traits::{StyleParseErrorKind, ToCss};
use style_traits::values::SequenceWriter;
use values::computed::font::FamilyName;
#[cfg(feature = "gecko")]
use values::specified::font::{AbsoluteFontWeight, FontStretch as SpecifiedFontStretch};
#[cfg(feature = "gecko")]
use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings};
-#[cfg(feature = "gecko")]
-use values::specified::font::FontStyle as SpecifiedFontStyle;
+use values::specified::font::SpecifiedFontStyle;
+use values::generics::font::FontStyle as GenericFontStyle;
use values::specified::Angle;
use values::specified::url::SpecifiedUrl;
/// A source for a font-face rule.
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
#[derive(Clone, Debug, Eq, PartialEq, ToCss)]
pub enum Source {
/// A `url()` source.
@@ -142,26 +142,25 @@ pub enum FontStyle {
impl Parse for FontStyle {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
let style = SpecifiedFontStyle::parse(context, input)?;
Ok(match style {
- SpecifiedFontStyle::Normal => FontStyle::Normal,
- SpecifiedFontStyle::Italic => FontStyle::Italic,
- SpecifiedFontStyle::Oblique(angle) => {
+ GenericFontStyle::Normal => FontStyle::Normal,
+ GenericFontStyle::Italic => FontStyle::Italic,
+ GenericFontStyle::Oblique(angle) => {
let second_angle = input.try(|input| {
SpecifiedFontStyle::parse_angle(context, input)
}).unwrap_or_else(|_| angle.clone());
FontStyle::Oblique(angle, second_angle)
}
- SpecifiedFontStyle::System(..) => unreachable!(),
})
}
}
impl ToCss for FontStyle {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: fmt::Write,
--- a/servo/components/style/gecko/rules.rs
+++ b/servo/components/style/gecko/rules.rs
@@ -11,17 +11,17 @@ use font_face::{FontDisplay, FontWeight,
use gecko_bindings::structs::{self, nsCSSValue};
use gecko_bindings::sugar::ns_css_value::ToNsCssValue;
use properties::longhands::font_language_override;
use std::str;
use values::computed::font::FamilyName;
use values::generics::font::FontTag;
use values::specified::font::{AbsoluteFontWeight, FontStretch as SpecifiedFontStretch};
use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings};
-use values::specified::font::FontStyle as SpecifiedFontStyle;
+use values::specified::font::SpecifiedFontStyle;
impl<'a> ToNsCssValue for &'a FamilyName {
fn convert(self, nscssvalue: &mut nsCSSValue) {
nscssvalue.set_string_from_atom(&self.name)
}
}
impl<'a> ToNsCssValue for &'a SpecifiedFontStretch {
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -2620,17 +2620,17 @@ fn static_assert() {
let stretch = self.gecko.mFont.stretch as f32;
debug_assert!(stretch >= 0.);
NonNegative(Percentage(stretch))
}
pub fn set_font_style(&mut self, v: longhands::font_style::computed_value::T) {
- use values::computed::font::FontStyle;
+ use values::generics::font::FontStyle;
self.gecko.mFont.style = match v {
FontStyle::Normal => structs::NS_STYLE_FONT_STYLE_NORMAL,
FontStyle::Italic => structs::NS_STYLE_FONT_STYLE_ITALIC,
// FIXME(emilio): Honor the angle.
FontStyle::Oblique(ref _angle) => structs::NS_STYLE_FONT_STYLE_OBLIQUE,
} as u8;
}
${impl_simple_copy('font_style', 'mFont.style')}
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -13,18 +13,18 @@
animation_value_type="discrete",
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-family",
servo_restyle_damage="rebuild_and_reflow")}
${helpers.predefined_type(
"font-style",
"FontStyle",
- initial_value="computed::FontStyle::Normal",
- initial_specified_value="specified::FontStyle::Normal",
+ initial_value="computed::FontStyle::normal()",
+ initial_specified_value="specified::FontStyle::normal()",
# FIXME(emilio): This won't handle clamping correctly.
animation_value_type="ComputedValue",
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-style",
servo_restyle_damage="rebuild_and_reflow",
)}
<% font_variant_caps_custom_consts= { "small-caps": "SMALLCAPS",
--- a/servo/components/style/style_adjuster.rs
+++ b/servo/components/style/style_adjuster.rs
@@ -354,18 +354,18 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
}
}
/// When mathvariant is not "none", font-weight and font-style are
/// both forced to "normal".
#[cfg(feature = "gecko")]
fn adjust_for_mathvariant(&mut self) {
use properties::longhands::_moz_math_variant::computed_value::T as MozMathVariant;
- use properties::longhands::font_style::computed_value::T as FontStyle;
use properties::longhands::font_weight::computed_value::T as FontWeight;
+ use values::generics::font::FontStyle;
if self.style.get_font().clone__moz_math_variant() != MozMathVariant::None {
let font_style = self.style.mutate_font();
font_style.set_font_weight(FontWeight::normal());
font_style.set_font_style(FontStyle::Normal);
}
}
/// This implements an out-of-date spec. The new spec moves the handling of
--- a/servo/components/style/values/computed/font.rs
+++ b/servo/components/style/values/computed/font.rs
@@ -18,17 +18,17 @@ use std::fmt::{self, Write};
#[cfg(feature = "gecko")]
use std::hash::{Hash, Hasher};
#[cfg(feature = "servo")]
use std::slice;
use style_traits::{CssWriter, ParseError, ToCss};
use values::CSSFloat;
use values::animated::{ToAnimatedValue, ToAnimatedZero};
use values::computed::{Angle, Context, Integer, NonNegativeLength, Number, ToComputedValue};
-use values::generics::font::{FeatureTagValue, FontSettings};
+use values::generics::font::{self as generics, FeatureTagValue, FontSettings};
use values::generics::font::{KeywordInfo as GenericKeywordInfo, VariationValue};
use values::specified::font::{self as specified, MIN_FONT_WEIGHT, MAX_FONT_WEIGHT};
use values::specified::length::{FontBaseSize, NoCalcLength};
pub use values::computed::Length as MozScriptMinSize;
pub use values::specified::font::{FontSynthesis, MozScriptSizeMultiplier, XLang, XTextZoom};
pub use values::computed::NonNegativePercentage as FontStretch;
@@ -826,69 +826,61 @@ impl ToComputedValue for specified::MozS
}
fn from_computed_value(other: &i8) -> Self {
specified::MozScriptLevel::MozAbsolute(*other as i32)
}
}
/// The computed value of `font-style`.
-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf,
- PartialEq)]
-#[allow(missing_docs)]
-pub enum FontStyle {
- #[animation(error)]
- Normal,
- #[animation(error)]
- Italic,
- // FIXME(emilio): This needs to clamp really.
- Oblique(Angle),
-}
-
-impl ToAnimatedZero for FontStyle {
- #[inline]
- fn to_animated_zero(&self) -> Result<Self, ()> {
- use num_traits::Zero;
- Ok(FontStyle::Oblique(Angle::zero()))
- }
-}
+///
+/// FIXME(emilio): Angle should be a custom type to handle clamping during
+/// animation.
+pub type FontStyle = generics::FontStyle<Angle>;
impl FontStyle {
+ /// The `normal` value.
+ #[inline]
+ pub fn normal() -> Self {
+ generics::FontStyle::Normal
+ }
+
/// The default angle for font-style: oblique. This is 20deg per spec:
///
/// https://drafts.csswg.org/css-fonts-4/#valdef-font-style-oblique-angle
+ #[inline]
pub fn default_angle() -> Angle {
Angle::Deg(specified::DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES)
}
/// Get the font style from Gecko's nsFont struct.
#[cfg(feature = "gecko")]
pub fn from_gecko(kw: u8) -> Self {
use gecko_bindings::structs;
match kw as u32 {
- structs::NS_STYLE_FONT_STYLE_NORMAL => FontStyle::Normal,
- structs::NS_STYLE_FONT_STYLE_ITALIC => FontStyle::Italic,
+ structs::NS_STYLE_FONT_STYLE_NORMAL => generics::FontStyle::Normal,
+ structs::NS_STYLE_FONT_STYLE_ITALIC => generics::FontStyle::Italic,
// FIXME(emilio): Grab the angle when we honor it :)
- structs::NS_STYLE_FONT_STYLE_OBLIQUE => FontStyle::Oblique(Self::default_angle()),
+ structs::NS_STYLE_FONT_STYLE_OBLIQUE => generics::FontStyle::Oblique(Self::default_angle()),
_ => unreachable!("Unknown font style"),
}
}
}
impl ToCss for FontStyle {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: fmt::Write,
{
match *self {
- FontStyle::Normal => dest.write_str("normal"),
- FontStyle::Italic => dest.write_str("italic"),
- FontStyle::Oblique(ref angle) => {
+ 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)?;
}
Ok(())
}
}
--- a/servo/components/style/values/generics/font.rs
+++ b/servo/components/style/values/generics/font.rs
@@ -226,8 +226,22 @@ impl ToCss for KeywordSize {
false,
"We should never serialize specified values set via HTML presentation attributes"
);
"-servo-xxx-large"
},
})
}
}
+
+/// A generic value for the `font-style` property.
+///
+/// https://drafts.csswg.org/css-fonts-4/#font-style-prop
+#[allow(missing_docs)]
+#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf,
+ PartialEq, ToAnimatedValue, ToAnimatedZero)]
+pub enum FontStyle<Angle> {
+ #[animation(error)]
+ Normal,
+ #[animation(error)]
+ Italic,
+ Oblique(Angle),
+}
--- a/servo/components/style/values/specified/font.rs
+++ b/servo/components/style/values/specified/font.rs
@@ -16,17 +16,17 @@ use parser::{Parse, ParserContext};
use properties::longhands::system_font::SystemFont;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
use values::CustomIdent;
use values::computed::{Angle as ComputedAngle, Percentage as ComputedPercentage};
use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue};
use values::computed::font::{FamilyName, FontFamilyList, SingleFontFamily};
use values::generics::NonNegative;
-use values::generics::font::{FeatureTagValue, FontSettings, FontTag};
+use values::generics::font::{self as generics, FeatureTagValue, FontSettings, FontTag};
use values::generics::font::{KeywordInfo as GenericKeywordInfo, KeywordSize, VariationValue};
use values::specified::{AllowQuirks, Angle, Integer, LengthOrPercentage, NoCalcLength, Number, Percentage};
use values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX};
const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8;
const DEFAULT_SCRIPT_SIZE_MULTIPLIER: f64 = 0.71;
/// The minimum font-weight value per:
@@ -186,64 +186,83 @@ impl Parse for AbsoluteFontWeight {
Ok(try_match_ident_ignore_ascii_case! { input,
"normal" => AbsoluteFontWeight::Normal,
"bold" => AbsoluteFontWeight::Bold,
})
}
}
-/// A specified value for the `font-style` property.
-///
-/// https://drafts.csswg.org/css-fonts-4/#font-style-prop
-///
-/// FIXME(emilio): It'd be nice to share more code with computed::FontStyle,
-/// except the system font stuff makes it kind of a pain.
-#[allow(missing_docs)]
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
-pub enum FontStyle {
- Normal,
- Italic,
- Oblique(Angle),
- System(SystemFont),
+/// The specified value of the `font-style` property, without the system font
+/// crap.
+pub type SpecifiedFontStyle = generics::FontStyle<Angle>;
+
+impl ToCss for SpecifiedFontStyle {
+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
+ where
+ 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)?;
+ }
+ Ok(())
+ }
+ }
+ }
}
-impl ToComputedValue for FontStyle {
+impl Parse for SpecifiedFontStyle {
+ fn parse<'i, 't>(
+ context: &ParserContext,
+ input: &mut Parser<'i, 't>,
+ ) -> Result<Self, ParseError<'i>> {
+ Ok(try_match_ident_ignore_ascii_case! { input,
+ "normal" => generics::FontStyle::Normal,
+ "italic" => generics::FontStyle::Italic,
+ "oblique" => {
+ let angle = input.try(|input| Self::parse_angle(context, input))
+ .unwrap_or_else(|_| Self::default_angle());
+
+ generics::FontStyle::Oblique(angle)
+ }
+ })
+ }
+}
+
+impl ToComputedValue for SpecifiedFontStyle {
type ComputedValue = computed::FontStyle;
- fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
+ fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
match *self {
- FontStyle::Normal => computed::FontStyle::Normal,
- FontStyle::Italic => computed::FontStyle::Italic,
- FontStyle::Oblique(ref angle) => {
- computed::FontStyle::Oblique(angle.to_computed_value(context))
+ generics::FontStyle::Normal => generics::FontStyle::Normal,
+ generics::FontStyle::Italic => generics::FontStyle::Italic,
+ generics::FontStyle::Oblique(ref angle) => {
+ generics::FontStyle::Oblique(Self::compute_angle(angle))
}
- #[cfg(feature = "gecko")]
- FontStyle::System(..) => context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_style
- .clone(),
- #[cfg(not(feature = "gecko"))]
- FontStyle::System(_) => unreachable!(),
}
}
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
match *computed {
- computed::FontStyle::Normal => FontStyle::Normal,
- computed::FontStyle::Italic => FontStyle::Italic,
- computed::FontStyle::Oblique(ref angle) => {
- FontStyle::Oblique(Angle::from_computed_value(angle))
+ generics::FontStyle::Normal => generics::FontStyle::Normal,
+ generics::FontStyle::Italic => generics::FontStyle::Italic,
+ generics::FontStyle::Oblique(ref angle) => {
+ generics::FontStyle::Oblique(Angle::from_computed_value(angle))
}
}
}
}
+
/// The default angle for `font-style: oblique`.
///
/// NOTE(emilio): As of right now this diverges from the spec, which specifies
/// 20, because it's not updated yet to account for the resolution in:
///
/// https://github.com/w3c/csswg-drafts/issues/2295
pub const DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES: f32 = 14.;
@@ -253,31 +272,17 @@ pub const DEFAULT_FONT_STYLE_OBLIQUE_ANG
/// invalid and are treated as parse errors.
///
/// The maximum angle value that `font-style: oblique` should compute to.
pub const FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES: f32 = 90.;
/// The minimum angle value that `font-style: oblique` should compute to.
pub const FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES: f32 = -90.;
-impl FontStyle {
- /// More system font copy-pasta.
- pub fn system_font(f: SystemFont) -> Self {
- FontStyle::System(f)
- }
-
- /// Retreive a SystemFont from FontStyle.
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontStyle::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
-
+impl SpecifiedFontStyle {
/// Gets a clamped angle from a specified Angle.
pub fn compute_angle(angle: &Angle) -> ComputedAngle {
ComputedAngle::Deg(
angle.degrees()
.max(FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES)
.min(FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES)
)
}
@@ -307,52 +312,75 @@ impl FontStyle {
pub fn default_angle() -> Angle {
Angle::from_degrees(
DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES,
/* was_calc = */ false,
)
}
}
-impl ToCss for FontStyle {
- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
- where
- W: Write,
- {
+/// The specified value of the `font-style` property.
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
+#[allow(missing_docs)]
+pub enum FontStyle {
+ Specified(SpecifiedFontStyle),
+ System(SystemFont),
+}
+
+impl FontStyle {
+ /// Return the `normal` value.
+ #[inline]
+ pub fn normal() -> Self {
+ FontStyle::Specified(generics::FontStyle::Normal)
+ }
+
+ /// More system font copy-pasta.
+ pub fn system_font(f: SystemFont) -> Self {
+ FontStyle::System(f)
+ }
+
+ /// Retreive a SystemFont from FontStyle.
+ pub fn get_system(&self) -> Option<SystemFont> {
+ if let FontStyle::System(s) = *self {
+ Some(s)
+ } else {
+ None
+ }
+ }
+}
+
+impl ToComputedValue for FontStyle {
+ type ComputedValue = computed::FontStyle;
+
+ fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self {
- FontStyle::Normal => dest.write_str("normal"),
- FontStyle::Italic => dest.write_str("italic"),
- FontStyle::Oblique(ref angle) => {
- dest.write_str("oblique")?;
- if *angle != Self::default_angle() {
- dest.write_char(' ')?;
- angle.to_css(dest)?;
- }
- Ok(())
- }
- FontStyle::System(ref s) => s.to_css(dest),
+ FontStyle::Specified(ref specified) => specified.to_computed_value(context),
+ #[cfg(feature = "gecko")]
+ FontStyle::System(..) => context
+ .cached_system_font
+ .as_ref()
+ .unwrap()
+ .font_style
+ .clone(),
+ #[cfg(not(feature = "gecko"))]
+ FontStyle::System(_) => unreachable!(),
}
}
+
+ fn from_computed_value(computed: &Self::ComputedValue) -> Self {
+ FontStyle::Specified(SpecifiedFontStyle::from_computed_value(computed))
+ }
}
impl Parse for FontStyle {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
- Ok(try_match_ident_ignore_ascii_case! { input,
- "normal" => FontStyle::Normal,
- "italic" => FontStyle::Italic,
- "oblique" => {
- let angle = input.try(|input| Self::parse_angle(context, input))
- .unwrap_or_else(|_| Self::default_angle());
-
- FontStyle::Oblique(angle)
- }
- })
+ Ok(FontStyle::Specified(SpecifiedFontStyle::parse(context, input)?))
}
}
/// A value for the `font-stretch` property.
///
/// https://drafts.csswg.org/css-fonts-4/#font-stretch-prop
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -5403,17 +5403,18 @@ pub extern "C" fn Servo_ParseFontShortha
value: *const nsAString,
data: *mut URLExtraData,
family: *mut structs::RefPtr<structs::SharedFontList>,
style: nsCSSValueBorrowedMut,
stretch: nsCSSValueBorrowedMut,
weight: nsCSSValueBorrowedMut
) -> bool {
use style::properties::shorthands::font;
- use style::values::specified::font::{FontFamily, FontWeight, FontStyle};
+ use style::values::generics::font::FontStyle as GenericFontStyle;
+ use style::values::specified::font::{FontFamily, FontWeight, FontStyle, SpecifiedFontStyle};
let string = unsafe { (*value).to_string() };
let mut input = ParserInput::new(&string);
let mut parser = Parser::new(&mut input);
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
let context = ParserContext::new(
Origin::Author,
url_data,
@@ -5428,25 +5429,29 @@ pub extern "C" fn Servo_ParseFontShortha
};
// The system font is not acceptable, so we return false.
let family = unsafe { &mut *family };
match font.font_family {
FontFamily::Values(list) => family.set_move(list.0),
FontFamily::System(_) => return false,
}
- match font.font_style {
- FontStyle::Normal => style.set_normal(),
- FontStyle::Italic => style.set_enum(structs::NS_FONT_STYLE_ITALIC as i32),
- FontStyle::Oblique(ref angle) => {
- style.set_angle(FontStyle::compute_angle(angle))
- }
+ let specified_font_style = match font.font_style {
+ FontStyle::Specified(ref s) => s,
FontStyle::System(_) => return false,
};
+ match specified_font_style {
+ GenericFontStyle::Normal => style.set_normal(),
+ GenericFontStyle::Italic => style.set_enum(structs::NS_FONT_STYLE_ITALIC as i32),
+ GenericFontStyle::Oblique(ref angle) => {
+ style.set_angle(SpecifiedFontStyle::compute_angle(angle))
+ }
+ }
+
if font.font_stretch.get_system().is_some() {
return false;
}
stretch.set_from(&font.font_stretch);
match font.font_weight {
FontWeight::Absolute(w) => weight.set_font_weight(w.compute().0),
// Resolve relative font weights against the initial of font-weight