Skip to content

Commit

Permalink
Fix parsing oblique angles in font-style descriptor
Browse files Browse the repository at this point in the history
Fixes #416
  • Loading branch information
devongovett committed Feb 11, 2023
1 parent 4443411 commit 0e84e8e
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 8 deletions.
18 changes: 18 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10041,6 +10041,24 @@ mod tests {
"@font-face {unicode-range: u+????, U+1????, U+10????;}",
"@font-face{unicode-range:U+????,U+1????,U+10????}",
);
minify_test(r#"
@font-face {
font-family: Inter;
font-style: oblique 0deg 10deg;
font-weight: 100 900;
src: url("../fonts/Inter.var.woff2?v=3.19") format("woff2");
font-display: swap;
}
"#, "@font-face{font-family:Inter;font-style:oblique 0deg 10deg;font-weight:100 900;src:url(../fonts/Inter.var.woff2?v=3.19)format(\"woff2\");font-display:swap}");
minify_test(r#"
@font-face {
font-family: Inter;
font-style: oblique 14deg 14deg;
font-weight: 100 900;
src: url("../fonts/Inter.var.woff2?v=3.19") format("woff2");
font-display: swap;
}
"#, "@font-face{font-family:Inter;font-style:oblique;font-weight:100 900;src:url(../fonts/Inter.var.woff2?v=3.19)format(\"woff2\");font-display:swap}");
}

#[test]
Expand Down
14 changes: 8 additions & 6 deletions src/properties/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ pub enum FontStyle {
/// Italic font style.
Italic,
/// Oblique font style, with a custom angle.
Oblique(#[cfg_attr(feature = "serde", serde(default = "default_oblique_angle"))] Angle),
Oblique(#[cfg_attr(feature = "serde", serde(default = "FontStyle::default_oblique_angle"))] Angle),
}

impl Default for FontStyle {
Expand All @@ -461,9 +461,11 @@ impl Default for FontStyle {
}
}

#[inline]
fn default_oblique_angle() -> Angle {
Angle::Deg(14.0)
impl FontStyle {
#[inline]
pub(crate) fn default_oblique_angle() -> Angle {
Angle::Deg(14.0)
}
}

impl<'i> Parse<'i> for FontStyle {
Expand All @@ -474,7 +476,7 @@ impl<'i> Parse<'i> for FontStyle {
"normal" => Ok(FontStyle::Normal),
"italic" => Ok(FontStyle::Italic),
"oblique" => {
let angle = input.try_parse(Angle::parse).unwrap_or(default_oblique_angle());
let angle = input.try_parse(Angle::parse).unwrap_or(FontStyle::default_oblique_angle());
Ok(FontStyle::Oblique(angle))
},
_ => Err(location.new_unexpected_token_error(
Expand All @@ -494,7 +496,7 @@ impl ToCss for FontStyle {
FontStyle::Italic => dest.write_str("italic"),
FontStyle::Oblique(angle) => {
dest.write_str("oblique")?;
if *angle != Angle::Deg(14.0) {
if *angle != FontStyle::default_oblique_angle() {
dest.write_char(' ')?;
angle.to_css(dest)?;
}
Expand Down
74 changes: 72 additions & 2 deletions src/rules/font_face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use crate::error::{ParserError, PrinterError};
use crate::macros::enum_property;
use crate::printer::Printer;
use crate::properties::custom::CustomProperty;
use crate::properties::font::{FontFamily, FontStretch, FontStyle, FontWeight};
use crate::properties::font::{FontFamily, FontStretch, FontStyle as FontStyleProperty, FontWeight};
use crate::stylesheet::ParserOptions;
use crate::traits::{Parse, ToCss};
use crate::values::angle::Angle;
use crate::values::size::Size2D;
use crate::values::string::CowArcStr;
use crate::values::url::Url;
Expand Down Expand Up @@ -369,6 +370,73 @@ impl ToCss for UnicodeRange {
}
}

/// A value for the [font-style](https://w3c.github.io/csswg-drafts/css-fonts/#descdef-font-face-font-style) descriptor in an `@font-face` rule.
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "visitor", derive(Visit))]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(tag = "type", content = "value", rename_all = "kebab-case")
)]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
pub enum FontStyle {
/// Normal font style.
Normal,
/// Italic font style.
Italic,
/// Oblique font style, with a custom angle.
Oblique(#[cfg_attr(feature = "serde", serde(default = "FontStyle::default_oblique_angle"))] Size2D<Angle>),
}

impl Default for FontStyle {
fn default() -> FontStyle {
FontStyle::Normal
}
}

impl FontStyle {
#[inline]
fn default_oblique_angle() -> Size2D<Angle> {
Size2D(
FontStyleProperty::default_oblique_angle(),
FontStyleProperty::default_oblique_angle(),
)
}
}

impl<'i> Parse<'i> for FontStyle {
fn parse<'t>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, ParserError<'i>>> {
Ok(match FontStyleProperty::parse(input)? {
FontStyleProperty::Normal => FontStyle::Normal,
FontStyleProperty::Italic => FontStyle::Italic,
FontStyleProperty::Oblique(angle) => {
let second_angle = input.try_parse(Angle::parse).unwrap_or_else(|_| angle.clone());
FontStyle::Oblique(Size2D(angle, second_angle))
}
})
}
}

impl ToCss for FontStyle {
fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
where
W: std::fmt::Write,
{
match self {
FontStyle::Normal => dest.write_str("normal"),
FontStyle::Italic => dest.write_str("italic"),
FontStyle::Oblique(angle) => {
dest.write_str("oblique")?;
if *angle != FontStyle::default_oblique_angle() {
dest.write_char(' ')?;
angle.to_css(dest)?;
}
Ok(())
}
}
}
}

pub(crate) struct FontFaceDeclarationParser;

/// Parse a declaration within {} block: `color: blue`
Expand All @@ -384,7 +452,9 @@ impl<'i> cssparser::DeclarationParser<'i> for FontFaceDeclarationParser {
macro_rules! property {
($property: ident, $type: ty) => {
if let Ok(c) = <$type>::parse(input) {
return Ok(FontFaceProperty::$property(c));
if input.expect_exhausted().is_ok() {
return Ok(FontFaceProperty::$property(c));
}
}
};
}
Expand Down

0 comments on commit 0e84e8e

Please sign in to comment.