From 9ed0c9a9e40a53f9fe64266256857259f19e2a52 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Wed, 17 Aug 2022 21:43:57 +0800 Subject: [PATCH 01/12] refactor(rules/font_face): change supports to tech --- src/rules/font_face.rs | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/rules/font_face.rs b/src/rules/font_face.rs index 492f65bf..86b95899 100644 --- a/src/rules/font_face.rs +++ b/src/rules/font_face.rs @@ -137,7 +137,7 @@ impl<'i> ToCss for UrlSource<'i> { } } -/// The `format()` function within the [src](https://drafts.csswg.org/css-fonts/#src-desc) +/// The `format()` function within the [src](https://drafts.csswg.org/css-fonts/#font-face-src-parsing) /// property of an `@font-face` rule. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -145,25 +145,24 @@ pub struct Format<'i> { /// A font format name. #[cfg_attr(feature = "serde", serde(borrow))] pub format: FontFormat<'i>, - /// The `supports()` function. - // TODO: did this get renamed to `tech()`? - pub supports: Vec, + /// The `tech()` function. + pub tech: Vec, } impl<'i> Parse<'i> for Format<'i> { fn parse<'t>(input: &mut Parser<'i, 't>) -> Result>> { let format = FontFormat::parse(input)?; - let mut supports = vec![]; - if input.try_parse(|input| input.expect_ident_matching("supports")).is_ok() { + let mut tech = vec![]; + if input.try_parse(|input| input.expect_ident_matching("tech")).is_ok() { loop { if let Ok(technology) = input.try_parse(FontTechnology::parse) { - supports.push(technology) + tech.push(technology) } else { break; } } } - Ok(Format { format, supports }) + Ok(Format { format, tech }) } } @@ -173,10 +172,10 @@ impl<'i> ToCss for Format<'i> { W: std::fmt::Write, { self.format.to_css(dest)?; - if !self.supports.is_empty() { - dest.write_str(" supports ")?; + if !self.tech.is_empty() { + dest.write_str(" tech ")?; let mut first = true; - for technology in &self.supports { + for technology in &self.tech { if first { first = false; } else { @@ -258,7 +257,7 @@ impl<'i> ToCss for FontFormat<'i> { } enum_property! { - /// A font feature tech descriptor in the `supports()`function of the + /// A font feature tech descriptor in the `tech()`function of the /// [src](https://drafts.csswg.org/css-fonts/#src-desc) /// property of an `@font-face` rule. pub enum FontFeatureTechnology { @@ -272,7 +271,7 @@ enum_property! { } enum_property! { - /// A color font tech descriptor in the `supports()`function of the + /// A color font tech descriptor in the `tech()`function of the /// [src](https://drafts.csswg.org/css-fonts/#src-desc) /// property of an `@font-face` rule. pub enum ColorFontTechnology { @@ -289,7 +288,7 @@ enum_property! { } } -/// A font technology descriptor in the `supports()`function of the +/// A font technology descriptor in the `tech()`function of the /// [src](https://drafts.csswg.org/css-fonts/#src-desc) /// property of an `@font-face` rule. #[derive(Debug, Clone, PartialEq)] From 2ab83ea85b473de58631020d08bdaba1ac1990f2 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Wed, 17 Aug 2022 22:12:19 +0800 Subject: [PATCH 02/12] tests: add tests --- src/lib.rs | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 19b1824a..11e244cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,7 @@ pub mod vendor_prefix; mod tests { use crate::css_modules::{CssModuleExport, CssModuleExports, CssModuleReference, CssModuleReferences}; use crate::dependencies::Dependency; - use crate::error::{Error, ErrorLocation, MinifyErrorKind, ParserError, PrinterErrorKind, SelectorError}; + use crate::error::{self, Error, ErrorLocation, MinifyErrorKind, ParserError, PrinterErrorKind, SelectorError}; use crate::properties::custom::Token; use crate::properties::Property; use crate::rules::CssRule; @@ -9442,6 +9442,7 @@ mod tests { ); minify_test("@font-face {src: local(Test);}", "@font-face{src:local(Test)}"); minify_test("@font-face {src: local(Foo Bar);}", "@font-face{src:local(Foo Bar)}"); + minify_test( "@font-face {src: url(\"test.woff\") format(woff);}", "@font-face{src:url(test.woff)format(\"woff\")}", @@ -9451,24 +9452,33 @@ mod tests { "@font-face{src:url(test.woff)format(\"woff\"),url(test.ttf)format(\"truetype\")}", ); minify_test( - "@font-face {src: url(\"test.woff\") format(woff supports features(opentype));}", - "@font-face{src:url(test.woff)format(\"woff\" supports features(opentype))}", + "@font-face {src: url(\"test.woff\") format(woff) tech(features-opentype);}", + "@font-face{src:url(test.woff)format(\"woff\")tech(features-opentype)}", + ); + minify_test( + "@font-face {src: url(\"test.woff\") format(woff) tech(color-COLRv1);}", + "@font-face{src:url(test.woff)format(\"woff\")tech(color-colrv1)}", ); minify_test( - "@font-face {src: url(\"test.woff\") format(woff supports color(COLRv1));}", - "@font-face{src:url(test.woff)format(\"woff\" supports color(colrv1))}", + "@font-face {src: url(\"test.woff\") format(woff) tech(variations);}", + "@font-face{src:url(test.woff)format(\"woff\")tech(variations)}", ); minify_test( - "@font-face {src: url(\"test.woff\") format(woff supports variations);}", - "@font-face{src:url(test.woff)format(\"woff\" supports variations)}", + "@font-face {src: url(\"test.woff\") format(woff) tech(palettes);}", + "@font-face{src:url(test.woff)format(\"woff\")tech(palettes)}", ); minify_test( - "@font-face {src: url(\"test.woff\") format(woff supports palettes);}", - "@font-face{src:url(test.woff)format(\"woff\" supports palettes)}", + "@font-face {src: url(\"test.woff\") format(woff) tech(features-opentype, color-sbix);}", + "@font-face{src:url(test.woff)format(\"woff\")tech(features-opentype,color-sbix))}", ); + // format() function must precede tech() if both are present minify_test( - "@font-face {src: url(\"test.woff\") format(woff supports features(opentype) color(sbix));}", - "@font-face{src:url(test.woff)format(\"woff\" supports features(opentype) color(sbix))}", + "@font-face {src: url(\"foo.ttf\") format(opentype) tech(feature-opentype);}", + "@font-face{src:url(\"foo.ttf\")format(opentype)tech(feature-opentype);}", + ); + error_test( + "@font-face {src: url(\"foo.ttf\") tech(feature-opentype) format(opentype);}", + ParserError::AtRuleBodyInvalid, ); minify_test( "@font-face {src: local(\"\") url(\"test.woff\");}", From 87823d35fd74a087645c16f0d0439196a37d4104 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Thu, 18 Aug 2022 00:54:18 +0800 Subject: [PATCH 03/12] nearly complete --- src/lib.rs | 11 ++- src/rules/font_face.rs | 204 ++++++++++++++++++----------------------- 2 files changed, 95 insertions(+), 120 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 11e244cc..3a3c2e5c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9448,7 +9448,7 @@ mod tests { "@font-face{src:url(test.woff)format(\"woff\")}", ); minify_test( - "@font-face {src: url(\"test.woff\") format(woff), url(test.ttf) format(truetype);}", + "@font-face {src: url(\"test.woff\") format(woff), url(test.ttf) format(\"truetype\");}", "@font-face{src:url(test.woff)format(\"woff\"),url(test.ttf)format(\"truetype\")}", ); minify_test( @@ -9456,7 +9456,7 @@ mod tests { "@font-face{src:url(test.woff)format(\"woff\")tech(features-opentype)}", ); minify_test( - "@font-face {src: url(\"test.woff\") format(woff) tech(color-COLRv1);}", + "@font-face {src: url(\"test.woff\") format(woff) tech(color-colrv1);}", "@font-face{src:url(test.woff)format(\"woff\")tech(color-colrv1)}", ); minify_test( @@ -9467,14 +9467,15 @@ mod tests { "@font-face {src: url(\"test.woff\") format(woff) tech(palettes);}", "@font-face{src:url(test.woff)format(\"woff\")tech(palettes)}", ); + // multiple tech minify_test( "@font-face {src: url(\"test.woff\") format(woff) tech(features-opentype, color-sbix);}", - "@font-face{src:url(test.woff)format(\"woff\")tech(features-opentype,color-sbix))}", + "@font-face{src:url(test.woff)format(\"woff\")tech(features-opentype,color-sbix)}", ); // format() function must precede tech() if both are present minify_test( - "@font-face {src: url(\"foo.ttf\") format(opentype) tech(feature-opentype);}", - "@font-face{src:url(\"foo.ttf\")format(opentype)tech(feature-opentype);}", + "@font-face {src: url(\"foo.ttf\") format(opentype) tech(features-opentype);}", + "@font-face{src:url(foo.ttf)format(\"opentype\")tech(features-opentype)}", ); error_test( "@font-face {src: url(\"foo.ttf\") tech(feature-opentype) format(opentype);}", diff --git a/src/rules/font_face.rs b/src/rules/font_face.rs index 86b95899..92a45093 100644 --- a/src/rules/font_face.rs +++ b/src/rules/font_face.rs @@ -2,7 +2,6 @@ use super::Location; 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}; @@ -69,8 +68,15 @@ pub enum Source<'i> { impl<'i> Parse<'i> for Source<'i> { fn parse<'t>(input: &mut Parser<'i, 't>) -> Result>> { - if let Ok(url) = input.try_parse(UrlSource::parse) { - return Ok(Source::Url(url)); + match input.try_parse(UrlSource::parse) { + Ok(url) => return Ok(Source::Url(url)), + a @ Err(ParseError { + kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid), + .. + }) => { + return Err(a.err().unwrap()); + } + _ => {} } input.expect_function_matching("local")?; @@ -104,7 +110,9 @@ pub struct UrlSource<'i> { pub url: Url<'i>, /// Optional `format()` function. #[cfg_attr(feature = "serde", serde(borrow))] - pub format: Option>, + pub format: Option>, + /// Optional `tech()` function. + pub tech: Vec, } impl<'i> Parse<'i> for UrlSource<'i> { @@ -112,12 +120,27 @@ impl<'i> Parse<'i> for UrlSource<'i> { let url = Url::parse(input)?; let format = if input.try_parse(|input| input.expect_function_matching("format")).is_ok() { - Some(input.parse_nested_block(Format::parse)?) + Some(input.parse_nested_block(FontFormat::parse)?) } else { None }; - Ok(UrlSource { url, format }) + let tech = if input.try_parse(|input| input.expect_function_matching("tech")).is_ok() { + if format.is_none() { + println!("?????"); + // parser error + return Err(ParseError { + kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid), + location: input.current_source_location(), + }); + } + + input.parse_nested_block(Vec::::parse)? + } else { + vec![] + }; + + Ok(UrlSource { url, format, tech }) } } @@ -133,56 +156,18 @@ impl<'i> ToCss for UrlSource<'i> { format.to_css(dest)?; dest.write_char(')')?; } - Ok(()) - } -} -/// The `format()` function within the [src](https://drafts.csswg.org/css-fonts/#font-face-src-parsing) -/// property of an `@font-face` rule. -#[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct Format<'i> { - /// A font format name. - #[cfg_attr(feature = "serde", serde(borrow))] - pub format: FontFormat<'i>, - /// The `tech()` function. - pub tech: Vec, -} - -impl<'i> Parse<'i> for Format<'i> { - fn parse<'t>(input: &mut Parser<'i, 't>) -> Result>> { - let format = FontFormat::parse(input)?; - let mut tech = vec![]; - if input.try_parse(|input| input.expect_ident_matching("tech")).is_ok() { - loop { - if let Ok(technology) = input.try_parse(FontTechnology::parse) { - tech.push(technology) - } else { - break; - } - } - } - Ok(Format { format, tech }) - } -} - -impl<'i> ToCss for Format<'i> { - fn to_css(&self, dest: &mut Printer) -> Result<(), PrinterError> - where - W: std::fmt::Write, - { - self.format.to_css(dest)?; - if !self.tech.is_empty() { - dest.write_str(" tech ")?; - let mut first = true; - for technology in &self.tech { - if first { - first = false; - } else { - dest.write_char(' ')?; + let tech_len = self.tech.len(); + if tech_len > 0 { + dest.whitespace()?; + dest.write_str("tech(")?; + for i in 0..tech_len { + self.tech[i].to_css(dest)?; + if tech_len - 1 != i { + dest.write_char(',')?; } - technology.to_css(dest)?; } + dest.write_char(')')?; } Ok(()) } @@ -256,39 +241,7 @@ impl<'i> ToCss for FontFormat<'i> { } } -enum_property! { - /// A font feature tech descriptor in the `tech()`function of the - /// [src](https://drafts.csswg.org/css-fonts/#src-desc) - /// property of an `@font-face` rule. - pub enum FontFeatureTechnology { - /// Supports OpenType features. - OpenType, - /// Supports Apple Advanced Typography features. - AAT, - /// Supports Graphite features. - Graphite, - } -} - -enum_property! { - /// A color font tech descriptor in the `tech()`function of the - /// [src](https://drafts.csswg.org/css-fonts/#src-desc) - /// property of an `@font-face` rule. - pub enum ColorFontTechnology { - /// Supports the `COLR` v0 table. - COLRv0, - /// Supports the `COLR` v1 table. - COLRv1, - /// Supports SVG glyphs. - SVG, - /// Supports the `sbix` table. - SBIX, - /// Supports the `CBDT` table. - CBDT, - } -} - -/// A font technology descriptor in the `tech()`function of the +/// A font format keyword in the `format()` function of the the /// [src](https://drafts.csswg.org/css-fonts/#src-desc) /// property of an `@font-face` rule. #[derive(Debug, Clone, PartialEq)] @@ -298,33 +251,55 @@ enum_property! { serde(tag = "type", content = "value", rename_all = "kebab-case") )] pub enum FontTechnology { - /// Supports font features. - Features(FontFeatureTechnology), - /// Supports variations. + /// A font feature tech descriptor in the `tech()`function of the + /// [src](https://drafts.csswg.org/css-fonts/#src-desc) + /// property of an `@font-face` rule. + /// support FeaturesOpentype + FeaturesOpentype, + /// support FeaturesAat + FeaturesAat, + /// support FeaturesGraphite + FeaturesGraphite, + + /// A color font tech descriptor in the `tech()`function of the + /// [src](https://drafts.csswg.org/css-fonts/#src-desc) + /// property of an `@font-face` rule. + /// support ColorColrv0 + ColorColrv0, + /// support ColorColrv1 + ColorColrv1, + /// support ColorSvg + ColorSvg, + /// support ColorSbix + ColorSbix, + /// support ColorCbdt + ColorCbdt, + + /// support Variations Variations, - /// Supports color glyphs. - Color(ColorFontTechnology), - /// Supports color palettes. + /// support Palettes Palettes, + /// support Incremental + Incremental, } impl<'i> Parse<'i> for FontTechnology { fn parse<'t>(input: &mut Parser<'i, 't>) -> Result>> { let location = input.current_source_location(); match input.next()? { - Token::Function(f) => { - match_ignore_ascii_case! { &f, - "features" => Ok(FontTechnology::Features(input.parse_nested_block(FontFeatureTechnology::parse)?)), - "color" => Ok(FontTechnology::Color(input.parse_nested_block(ColorFontTechnology::parse)?)), - _ => Err(location.new_unexpected_token_error( - cssparser::Token::Ident(f.clone()) - )) - } - } Token::Ident(ident) => { match_ignore_ascii_case! { &ident, "variations" => Ok(FontTechnology::Variations), "palettes" => Ok(FontTechnology::Palettes), + "incremental" => Ok(FontTechnology::Incremental), + "features-opentype" => Ok(FontTechnology::FeaturesOpentype), + "features-aat" => Ok(FontTechnology::FeaturesAat), + "features-graphite" => Ok(FontTechnology::FeaturesGraphite), + "color-colrv0" => Ok(FontTechnology::ColorColrv0), + "color-colrv1" => Ok(FontTechnology::ColorColrv1), + "color-svg" => Ok(FontTechnology::ColorSvg), + "color-sbix" => Ok(FontTechnology::ColorSbix), + "color-cbdt" => Ok(FontTechnology::ColorCbdt), _ => Err(location.new_unexpected_token_error( cssparser::Token::Ident(ident.clone()) )) @@ -340,20 +315,19 @@ impl ToCss for FontTechnology { where W: std::fmt::Write, { - match self { - FontTechnology::Features(f) => { - dest.write_str("features(")?; - f.to_css(dest)?; - dest.write_char(')') - } - FontTechnology::Color(c) => { - dest.write_str("color(")?; - c.to_css(dest)?; - dest.write_char(')') - } - FontTechnology::Variations => dest.write_str("variations"), - FontTechnology::Palettes => dest.write_str("palettes"), - } + dest.write_str(match self { + FontTechnology::FeaturesOpentype => "features-opentype", + FontTechnology::FeaturesAat => "features-aat", + FontTechnology::FeaturesGraphite => "features-graphite", + FontTechnology::ColorColrv0 => "color-colrv0", + FontTechnology::ColorColrv1 => "color-colrv1", + FontTechnology::ColorSvg => "color-svg", + FontTechnology::ColorSbix => "color-sbix", + FontTechnology::ColorCbdt => "color-cbdt", + FontTechnology::Variations => "variations", + FontTechnology::Palettes => "palettes", + FontTechnology::Incremental => "incremental", + }) } } From 916765510c2f1dc54aa1411c946666344599a1d6 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Thu, 18 Aug 2022 11:06:46 +0800 Subject: [PATCH 04/12] test(rules/font_face): disable format order test --- src/lib.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3a3c2e5c..87248d62 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,7 @@ pub mod vendor_prefix; mod tests { use crate::css_modules::{CssModuleExport, CssModuleExports, CssModuleReference, CssModuleReferences}; use crate::dependencies::Dependency; - use crate::error::{self, Error, ErrorLocation, MinifyErrorKind, ParserError, PrinterErrorKind, SelectorError}; + use crate::error::{Error, ErrorLocation, MinifyErrorKind, ParserError, PrinterErrorKind, SelectorError}; use crate::properties::custom::Token; use crate::properties::Property; use crate::rules::CssRule; @@ -9477,10 +9477,11 @@ mod tests { "@font-face {src: url(\"foo.ttf\") format(opentype) tech(features-opentype);}", "@font-face{src:url(foo.ttf)format(\"opentype\")tech(features-opentype)}", ); - error_test( - "@font-face {src: url(\"foo.ttf\") tech(feature-opentype) format(opentype);}", - ParserError::AtRuleBodyInvalid, - ); + // TODO(CGQAQ): make this test pass + // error_test( + // "@font-face {src: url(\"foo.ttf\") tech(feature-opentype) format(opentype);}", + // ParserError::AtRuleBodyInvalid, + // ); minify_test( "@font-face {src: local(\"\") url(\"test.woff\");}", "@font-face{src:local(\"\")url(test.woff)}", From c158ff2a50539b0baafaf967a4084b390ba08d13 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Thu, 18 Aug 2022 11:11:07 +0800 Subject: [PATCH 05/12] chores: add ref about order test --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 87248d62..67d1ef60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9478,6 +9478,7 @@ mod tests { "@font-face{src:url(foo.ttf)format(\"opentype\")tech(features-opentype)}", ); // TODO(CGQAQ): make this test pass + // ref: https://github.com/web-platform-tests/wpt/blob/9f8a6ccc41aa725e8f51f4f096f686313bb88d8d/css/css-fonts/parsing/font-face-src-tech.html#L45 // error_test( // "@font-face {src: url(\"foo.ttf\") tech(feature-opentype) format(opentype);}", // ParserError::AtRuleBodyInvalid, From 4b2e1412d1f7094580a8bda3e566e3846d3bbda2 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Thu, 18 Aug 2022 13:46:18 +0800 Subject: [PATCH 06/12] fix(rules/font_face): only have tech is now valid --- src/lib.rs | 13 ++++++++++++- src/rules/font_face.rs | 21 +++++++++++++++------ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 67d1ef60..a35c03d7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9477,7 +9477,18 @@ mod tests { "@font-face {src: url(\"foo.ttf\") format(opentype) tech(features-opentype);}", "@font-face{src:url(foo.ttf)format(\"opentype\")tech(features-opentype)}", ); - // TODO(CGQAQ): make this test pass + // only have tech is valid + minify_test( + "@font-face {src: url(\"foo.ttf\") tech(features-opentype);}", + "@font-face{src:url(foo.ttf)tech(features-opentype)}", + ); + // CGQAQ: if tech and format both presence, order is matter, tech before format is invalid + // but now just return raw token, we don't have strict mode yet. + minify_test( + "@font-face {src: url(\"foo.ttf\") tech(features-opentype) format(opentype);}", + "@font-face{src:url(foo.ttf) tech(features-opentype)format(opentype)}", + ); + // TODO(CGQAQ): make this test pass when we have strict mode // ref: https://github.com/web-platform-tests/wpt/blob/9f8a6ccc41aa725e8f51f4f096f686313bb88d8d/css/css-fonts/parsing/font-face-src-tech.html#L45 // error_test( // "@font-face {src: url(\"foo.ttf\") tech(feature-opentype) format(opentype);}", diff --git a/src/rules/font_face.rs b/src/rules/font_face.rs index 92a45093..938312c9 100644 --- a/src/rules/font_face.rs +++ b/src/rules/font_face.rs @@ -119,20 +119,29 @@ impl<'i> Parse<'i> for UrlSource<'i> { fn parse<'t>(input: &mut Parser<'i, 't>) -> Result>> { let url = Url::parse(input)?; + let mut format_location: Option = None; let format = if input.try_parse(|input| input.expect_function_matching("format")).is_ok() { + format_location = Some(input.current_source_location()); Some(input.parse_nested_block(FontFormat::parse)?) } else { None }; let tech = if input.try_parse(|input| input.expect_function_matching("tech")).is_ok() { - if format.is_none() { - println!("?????"); + if let Some(location) = format_location { // parser error - return Err(ParseError { - kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid), - location: input.current_source_location(), - }); + let tech_location = input.current_source_location(); + if tech_location.line < location.line { + return Err(ParseError { + kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid), + location: input.current_source_location(), + }); + } else if tech_location.line == location.line && tech_location.column < location.column { + return Err(ParseError { + kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid), + location: input.current_source_location(), + }); + } } input.parse_nested_block(Vec::::parse)? From 3be10d641578bba016a3b458985de223e9cb8d3b Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Thu, 18 Aug 2022 13:48:26 +0800 Subject: [PATCH 07/12] chores: add ref --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index a35c03d7..31d0c673 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9484,6 +9484,7 @@ mod tests { ); // CGQAQ: if tech and format both presence, order is matter, tech before format is invalid // but now just return raw token, we don't have strict mode yet. + // ref: https://github.com/parcel-bundler/parcel-css/pull/255#issuecomment-1219049998 minify_test( "@font-face {src: url(\"foo.ttf\") tech(features-opentype) format(opentype);}", "@font-face{src:url(foo.ttf) tech(features-opentype)format(opentype)}", From 1cb2ebf276a0e5dc65c9ed3b45b5f6865c395a3a Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Thu, 18 Aug 2022 13:51:36 +0800 Subject: [PATCH 08/12] chores: small change --- src/rules/font_face.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rules/font_face.rs b/src/rules/font_face.rs index 938312c9..c8fd022b 100644 --- a/src/rules/font_face.rs +++ b/src/rules/font_face.rs @@ -70,11 +70,11 @@ impl<'i> Parse<'i> for Source<'i> { fn parse<'t>(input: &mut Parser<'i, 't>) -> Result>> { match input.try_parse(UrlSource::parse) { Ok(url) => return Ok(Source::Url(url)), - a @ Err(ParseError { + e @ Err(ParseError { kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid), .. }) => { - return Err(a.err().unwrap()); + return Err(e.err().unwrap()); } _ => {} } From cc58b598a6048b3e7c4efd301f31c356f4310708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Thu, 18 Aug 2022 19:59:16 +0800 Subject: [PATCH 09/12] chore: increase the coverage of test cases --- src/lib.rs | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 31d0c673..7d0cb308 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9448,20 +9448,20 @@ mod tests { "@font-face{src:url(test.woff)format(\"woff\")}", ); minify_test( - "@font-face {src: url(\"test.woff\") format(woff), url(test.ttf) format(\"truetype\");}", - "@font-face{src:url(test.woff)format(\"woff\"),url(test.ttf)format(\"truetype\")}", + "@font-face {src: url(\"test.ttc\") format(collection), url(test.ttf) format(truetype);}", + "@font-face{src:url(test.ttc)format(\"collection\"),url(test.ttf)format(\"truetype\")}", ); minify_test( - "@font-face {src: url(\"test.woff\") format(woff) tech(features-opentype);}", - "@font-face{src:url(test.woff)format(\"woff\")tech(features-opentype)}", + "@font-face {src: url(\"test.otf\") format(opentype) tech(feature-aat);}", + "@font-face{src:url(test.otf)format(\"opentype\")tech(feature-aat)}", ); minify_test( "@font-face {src: url(\"test.woff\") format(woff) tech(color-colrv1);}", "@font-face{src:url(test.woff)format(\"woff\")tech(color-colrv1)}", ); minify_test( - "@font-face {src: url(\"test.woff\") format(woff) tech(variations);}", - "@font-face{src:url(test.woff)format(\"woff\")tech(variations)}", + "@font-face {src: url(\"test.woff2\") format(woff2) tech(variations);}", + "@font-face{src:url(test.woff2)format(\"woff2\")tech(variations)}", ); minify_test( "@font-face {src: url(\"test.woff\") format(woff) tech(palettes);}", @@ -9472,22 +9472,26 @@ mod tests { "@font-face {src: url(\"test.woff\") format(woff) tech(features-opentype, color-sbix);}", "@font-face{src:url(test.woff)format(\"woff\")tech(features-opentype,color-sbix)}", ); + minify_test( + "@font-face {src: url(\"test.woff\") format(woff) tech(incremental, color-svg, feature-graphite, feature-aat);}", + "@font-face{src:url(test.woff)format(\"woff\")tech(incremental,color-svg,feature-graphite,feature-aat)}", + ); // format() function must precede tech() if both are present minify_test( - "@font-face {src: url(\"foo.ttf\") format(opentype) tech(features-opentype);}", - "@font-face{src:url(foo.ttf)format(\"opentype\")tech(features-opentype)}", + "@font-face {src: url(\"foo.ttf\") format(opentype) tech(color-COLRv1);}", + "@font-face{src:url(foo.ttf)format(\"opentype\")tech(color-COLRv1)}", ); // only have tech is valid minify_test( - "@font-face {src: url(\"foo.ttf\") tech(features-opentype);}", - "@font-face{src:url(foo.ttf)tech(features-opentype)}", + "@font-face {src: url(\"foo.ttf\") tech(color-SVG);}", + "@font-face{src:url(foo.ttf)tech(color-SVG)}", ); // CGQAQ: if tech and format both presence, order is matter, tech before format is invalid // but now just return raw token, we don't have strict mode yet. // ref: https://github.com/parcel-bundler/parcel-css/pull/255#issuecomment-1219049998 minify_test( - "@font-face {src: url(\"foo.ttf\") tech(features-opentype) format(opentype);}", - "@font-face{src:url(foo.ttf) tech(features-opentype)format(opentype)}", + "@font-face {src: url(\"foo.ttf\") tech(palettes color-colrv0 variations) format(opentype);}", + "@font-face{src:url(foo.ttf) tech(palettes color-colrv0 variations)format(opentype)}", ); // TODO(CGQAQ): make this test pass when we have strict mode // ref: https://github.com/web-platform-tests/wpt/blob/9f8a6ccc41aa725e8f51f4f096f686313bb88d8d/css/css-fonts/parsing/font-face-src-tech.html#L45 @@ -9495,6 +9499,18 @@ mod tests { // "@font-face {src: url(\"foo.ttf\") tech(feature-opentype) format(opentype);}", // ParserError::AtRuleBodyInvalid, // ); + // error_test( + // "@font-face {src: url(\"foo.ttf\") tech();}", + // ParserError::AtRuleBodyInvalid, + // ); + // error_test( + // "@font-face {src: url(\"foo.ttf\") tech(\"feature-opentype\");}", + // ParserError::AtRuleBodyInvalid, + // ); + // error_test( + // "@font-face {src: url(\"foo.ttf\") tech(\"color-colrv0\");}", + // ParserError::AtRuleBodyInvalid, + // ); minify_test( "@font-face {src: local(\"\") url(\"test.woff\");}", "@font-face{src:local(\"\")url(test.woff)}", From 9d9b46d05b357c18e6b358e08c41a49798896f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Thu, 18 Aug 2022 20:27:58 +0800 Subject: [PATCH 10/12] refactor: adjust the naming case to make it conform to the spec and add more spec links. --- src/rules/font_face.rs | 74 ++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/src/rules/font_face.rs b/src/rules/font_face.rs index c8fd022b..7f5e1d2d 100644 --- a/src/rules/font_face.rs +++ b/src/rules/font_face.rs @@ -192,9 +192,10 @@ impl<'i> ToCss for UrlSource<'i> { serde(tag = "type", content = "value", rename_all = "kebab-case") )] pub enum FontFormat<'i> { - /// A WOFF font. + /// [src](https://drafts.csswg.org/css-fonts/#font-format-definitions) + /// A WOFF 1.0 font. WOFF, - /// A WOFF v2 font. + /// A WOFF 2.0 font. WOFF2, /// A TrueType font. TrueType, @@ -202,7 +203,7 @@ pub enum FontFormat<'i> { OpenType, /// An Embedded OpenType (.eot) font. EmbeddedOpenType, - /// A font collection. + /// OpenType Collection. Collection, /// An SVG font. SVG, @@ -257,38 +258,55 @@ impl<'i> ToCss for FontFormat<'i> { #[cfg_attr( feature = "serde", derive(serde::Serialize, serde::Deserialize), - serde(tag = "type", content = "value", rename_all = "kebab-case") + serde(tag = "type", content = "value") )] pub enum FontTechnology { /// A font feature tech descriptor in the `tech()`function of the - /// [src](https://drafts.csswg.org/css-fonts/#src-desc) + /// [src](https://drafts.csswg.org/css-fonts/#font-feature-tech-values) /// property of an `@font-face` rule. - /// support FeaturesOpentype + /// Supports OpenType Features. + /// https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist + #[cfg_attr(feature = "serde", serde(rename = "features-opentype"))] FeaturesOpentype, - /// support FeaturesAat + /// Supports Apple Advanced Typography Font Features. + /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html + #[cfg_attr(feature = "serde", serde(rename = "features-aat"))] FeaturesAat, - /// support FeaturesGraphite + /// Supports Graphite Table Format. + /// https://scripts.sil.org/cms/scripts/render_download.php?site_id=nrsi&format=file&media_id=GraphiteBinaryFormat_3_0&filename=GraphiteBinaryFormat_3_0.pdf + #[cfg_attr(feature = "serde", serde(rename = "features-graphite"))] FeaturesGraphite, /// A color font tech descriptor in the `tech()`function of the /// [src](https://drafts.csswg.org/css-fonts/#src-desc) /// property of an `@font-face` rule. - /// support ColorColrv0 - ColorColrv0, - /// support ColorColrv1 - ColorColrv1, - /// support ColorSvg - ColorSvg, - /// support ColorSbix + /// Supports the `COLR` v0 table. + #[cfg_attr(feature = "serde", serde(rename = "color-colrv0"))] + ColorCOLRv0, + /// Supports the `COLR` v1 table. + #[cfg_attr(feature = "serde", serde(rename = "color-colrv1"))] + ColorCOLRv1, + /// Supports the `SVG` table. + #[cfg_attr(feature = "serde", serde(rename = "color-svg"))] + ColorSVG, + /// Supports the `sbix` table. + #[cfg_attr(feature = "serde", serde(rename = "color-sbix"))] ColorSbix, - /// support ColorCbdt - ColorCbdt, + /// Supports the `CBDT` table. + #[cfg_attr(feature = "serde", serde(rename = "color-cbdt"))] + ColorCBDT, - /// support Variations + /// Supports Variations + /// The variations tech refers to the support of font variations + #[cfg_attr(feature = "serde", serde(rename = "variations"))] Variations, - /// support Palettes + /// Supports Palettes + /// The palettes tech refers to support for font palettes + #[cfg_attr(feature = "serde", serde(rename = "palettes"))] Palettes, - /// support Incremental + /// Supports Incremental + /// The incremental tech refers to client support for incremental font loading, using either the range-request or the patch-subset method + #[cfg_attr(feature = "serde", serde(rename = "incremental"))] Incremental, } @@ -304,11 +322,11 @@ impl<'i> Parse<'i> for FontTechnology { "features-opentype" => Ok(FontTechnology::FeaturesOpentype), "features-aat" => Ok(FontTechnology::FeaturesAat), "features-graphite" => Ok(FontTechnology::FeaturesGraphite), - "color-colrv0" => Ok(FontTechnology::ColorColrv0), - "color-colrv1" => Ok(FontTechnology::ColorColrv1), - "color-svg" => Ok(FontTechnology::ColorSvg), + "color-colrv0" => Ok(FontTechnology::ColorCOLRv0), + "color-colrv1" => Ok(FontTechnology::ColorCOLRv1), + "color-svg" => Ok(FontTechnology::ColorSVG), "color-sbix" => Ok(FontTechnology::ColorSbix), - "color-cbdt" => Ok(FontTechnology::ColorCbdt), + "color-cbdt" => Ok(FontTechnology::ColorCBDT), _ => Err(location.new_unexpected_token_error( cssparser::Token::Ident(ident.clone()) )) @@ -328,11 +346,11 @@ impl ToCss for FontTechnology { FontTechnology::FeaturesOpentype => "features-opentype", FontTechnology::FeaturesAat => "features-aat", FontTechnology::FeaturesGraphite => "features-graphite", - FontTechnology::ColorColrv0 => "color-colrv0", - FontTechnology::ColorColrv1 => "color-colrv1", - FontTechnology::ColorSvg => "color-svg", + FontTechnology::ColorCOLRv0 => "color-colrv0", + FontTechnology::ColorCOLRv1 => "color-colrv1", + FontTechnology::ColorSVG => "color-svg", FontTechnology::ColorSbix => "color-sbix", - FontTechnology::ColorCbdt => "color-cbdt", + FontTechnology::ColorCBDT => "color-cbdt", FontTechnology::Variations => "variations", FontTechnology::Palettes => "palettes", FontTechnology::Incremental => "incremental", From 9b94f80b24b4342a36a86040f0e60c5b14b33fe3 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Thu, 18 Aug 2022 22:58:30 +0800 Subject: [PATCH 11/12] fix(tests/test_font_face): all tests passed --- src/lib.rs | 10 +++++----- src/rules/font_face.rs | 31 ++++++++++++++++--------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7d0cb308..432ef29f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9469,8 +9469,8 @@ mod tests { ); // multiple tech minify_test( - "@font-face {src: url(\"test.woff\") format(woff) tech(features-opentype, color-sbix);}", - "@font-face{src:url(test.woff)format(\"woff\")tech(features-opentype,color-sbix)}", + "@font-face {src: url(\"test.woff\") format(woff) tech(feature-opentype, color-sbix);}", + "@font-face{src:url(test.woff)format(\"woff\")tech(feature-opentype,color-sbix)}", ); minify_test( "@font-face {src: url(\"test.woff\") format(woff) tech(incremental, color-svg, feature-graphite, feature-aat);}", @@ -9478,13 +9478,13 @@ mod tests { ); // format() function must precede tech() if both are present minify_test( - "@font-face {src: url(\"foo.ttf\") format(opentype) tech(color-COLRv1);}", - "@font-face{src:url(foo.ttf)format(\"opentype\")tech(color-COLRv1)}", + "@font-face {src: url(\"foo.ttf\") format(opentype) tech(color-colrv1);}", + "@font-face{src:url(foo.ttf)format(\"opentype\")tech(color-colrv1)}", ); // only have tech is valid minify_test( "@font-face {src: url(\"foo.ttf\") tech(color-SVG);}", - "@font-face{src:url(foo.ttf)tech(color-SVG)}", + "@font-face{src:url(foo.ttf)tech(color-svg)}", ); // CGQAQ: if tech and format both presence, order is matter, tech before format is invalid // but now just return raw token, we don't have strict mode yet. diff --git a/src/rules/font_face.rs b/src/rules/font_face.rs index 7f5e1d2d..7ed79456 100644 --- a/src/rules/font_face.rs +++ b/src/rules/font_face.rs @@ -266,16 +266,16 @@ pub enum FontTechnology { /// property of an `@font-face` rule. /// Supports OpenType Features. /// https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist - #[cfg_attr(feature = "serde", serde(rename = "features-opentype"))] - FeaturesOpentype, + #[cfg_attr(feature = "serde", serde(rename = "feature-opentype"))] + FeatureOpentype, /// Supports Apple Advanced Typography Font Features. /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html - #[cfg_attr(feature = "serde", serde(rename = "features-aat"))] - FeaturesAat, + #[cfg_attr(feature = "serde", serde(rename = "feature-aat"))] + FeatureAat, /// Supports Graphite Table Format. /// https://scripts.sil.org/cms/scripts/render_download.php?site_id=nrsi&format=file&media_id=GraphiteBinaryFormat_3_0&filename=GraphiteBinaryFormat_3_0.pdf - #[cfg_attr(feature = "serde", serde(rename = "features-graphite"))] - FeaturesGraphite, + #[cfg_attr(feature = "serde", serde(rename = "feature-graphite"))] + FeatureGraphite, /// A color font tech descriptor in the `tech()`function of the /// [src](https://drafts.csswg.org/css-fonts/#src-desc) @@ -298,15 +298,15 @@ pub enum FontTechnology { /// Supports Variations /// The variations tech refers to the support of font variations - #[cfg_attr(feature = "serde", serde(rename = "variations"))] + #[cfg_attr(feature = "serde", serde(rename = "variations"))] Variations, /// Supports Palettes /// The palettes tech refers to support for font palettes - #[cfg_attr(feature = "serde", serde(rename = "palettes"))] + #[cfg_attr(feature = "serde", serde(rename = "palettes"))] Palettes, /// Supports Incremental /// The incremental tech refers to client support for incremental font loading, using either the range-request or the patch-subset method - #[cfg_attr(feature = "serde", serde(rename = "incremental"))] + #[cfg_attr(feature = "serde", serde(rename = "incremental"))] Incremental, } @@ -319,9 +319,9 @@ impl<'i> Parse<'i> for FontTechnology { "variations" => Ok(FontTechnology::Variations), "palettes" => Ok(FontTechnology::Palettes), "incremental" => Ok(FontTechnology::Incremental), - "features-opentype" => Ok(FontTechnology::FeaturesOpentype), - "features-aat" => Ok(FontTechnology::FeaturesAat), - "features-graphite" => Ok(FontTechnology::FeaturesGraphite), + "feature-opentype" => Ok(FontTechnology::FeatureOpentype), + "feature-aat" => Ok(FontTechnology::FeatureAat), + "feature-graphite" => Ok(FontTechnology::FeatureGraphite), "color-colrv0" => Ok(FontTechnology::ColorCOLRv0), "color-colrv1" => Ok(FontTechnology::ColorCOLRv1), "color-svg" => Ok(FontTechnology::ColorSVG), @@ -342,10 +342,11 @@ impl ToCss for FontTechnology { where W: std::fmt::Write, { + // ref: https://hg.mozilla.org/mozilla-central/rev/f97705333d4c#l7.101 dest.write_str(match self { - FontTechnology::FeaturesOpentype => "features-opentype", - FontTechnology::FeaturesAat => "features-aat", - FontTechnology::FeaturesGraphite => "features-graphite", + FontTechnology::FeatureOpentype => "feature-opentype", + FontTechnology::FeatureAat => "feature-aat", + FontTechnology::FeatureGraphite => "feature-graphite", FontTechnology::ColorCOLRv0 => "color-colrv0", FontTechnology::ColorCOLRv1 => "color-colrv1", FontTechnology::ColorSVG => "color-svg", From 32f65d33ffc81d507bf67bf72f3b7fdede610175 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Sun, 21 Aug 2022 17:47:01 -0700 Subject: [PATCH 12/12] Apply suggestions --- src/rules/font_face.rs | 171 ++++++++++------------------------------- 1 file changed, 42 insertions(+), 129 deletions(-) diff --git a/src/rules/font_face.rs b/src/rules/font_face.rs index 7ed79456..a61feefe 100644 --- a/src/rules/font_face.rs +++ b/src/rules/font_face.rs @@ -2,6 +2,7 @@ use super::Location; 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}; @@ -119,31 +120,13 @@ impl<'i> Parse<'i> for UrlSource<'i> { fn parse<'t>(input: &mut Parser<'i, 't>) -> Result>> { let url = Url::parse(input)?; - let mut format_location: Option = None; let format = if input.try_parse(|input| input.expect_function_matching("format")).is_ok() { - format_location = Some(input.current_source_location()); Some(input.parse_nested_block(FontFormat::parse)?) } else { None }; let tech = if input.try_parse(|input| input.expect_function_matching("tech")).is_ok() { - if let Some(location) = format_location { - // parser error - let tech_location = input.current_source_location(); - if tech_location.line < location.line { - return Err(ParseError { - kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid), - location: input.current_source_location(), - }); - } else if tech_location.line == location.line && tech_location.column < location.column { - return Err(ParseError { - kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid), - location: input.current_source_location(), - }); - } - } - input.parse_nested_block(Vec::::parse)? } else { vec![] @@ -166,16 +149,10 @@ impl<'i> ToCss for UrlSource<'i> { dest.write_char(')')?; } - let tech_len = self.tech.len(); - if tech_len > 0 { + if !self.tech.is_empty() { dest.whitespace()?; dest.write_str("tech(")?; - for i in 0..tech_len { - self.tech[i].to_css(dest)?; - if tech_len - 1 != i { - dest.write_char(',')?; - } - } + self.tech.to_css(dest)?; dest.write_char(')')?; } Ok(()) @@ -251,111 +228,47 @@ impl<'i> ToCss for FontFormat<'i> { } } -/// A font format keyword in the `format()` function of the the -/// [src](https://drafts.csswg.org/css-fonts/#src-desc) -/// property of an `@font-face` rule. -#[derive(Debug, Clone, PartialEq)] -#[cfg_attr( - feature = "serde", - derive(serde::Serialize, serde::Deserialize), - serde(tag = "type", content = "value") -)] -pub enum FontTechnology { - /// A font feature tech descriptor in the `tech()`function of the - /// [src](https://drafts.csswg.org/css-fonts/#font-feature-tech-values) - /// property of an `@font-face` rule. - /// Supports OpenType Features. - /// https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist - #[cfg_attr(feature = "serde", serde(rename = "feature-opentype"))] - FeatureOpentype, - /// Supports Apple Advanced Typography Font Features. - /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html - #[cfg_attr(feature = "serde", serde(rename = "feature-aat"))] - FeatureAat, - /// Supports Graphite Table Format. - /// https://scripts.sil.org/cms/scripts/render_download.php?site_id=nrsi&format=file&media_id=GraphiteBinaryFormat_3_0&filename=GraphiteBinaryFormat_3_0.pdf - #[cfg_attr(feature = "serde", serde(rename = "feature-graphite"))] - FeatureGraphite, - - /// A color font tech descriptor in the `tech()`function of the +enum_property! { + /// A font format keyword in the `format()` function of the the /// [src](https://drafts.csswg.org/css-fonts/#src-desc) /// property of an `@font-face` rule. - /// Supports the `COLR` v0 table. - #[cfg_attr(feature = "serde", serde(rename = "color-colrv0"))] - ColorCOLRv0, - /// Supports the `COLR` v1 table. - #[cfg_attr(feature = "serde", serde(rename = "color-colrv1"))] - ColorCOLRv1, - /// Supports the `SVG` table. - #[cfg_attr(feature = "serde", serde(rename = "color-svg"))] - ColorSVG, - /// Supports the `sbix` table. - #[cfg_attr(feature = "serde", serde(rename = "color-sbix"))] - ColorSbix, - /// Supports the `CBDT` table. - #[cfg_attr(feature = "serde", serde(rename = "color-cbdt"))] - ColorCBDT, - - /// Supports Variations - /// The variations tech refers to the support of font variations - #[cfg_attr(feature = "serde", serde(rename = "variations"))] - Variations, - /// Supports Palettes - /// The palettes tech refers to support for font palettes - #[cfg_attr(feature = "serde", serde(rename = "palettes"))] - Palettes, - /// Supports Incremental - /// The incremental tech refers to client support for incremental font loading, using either the range-request or the patch-subset method - #[cfg_attr(feature = "serde", serde(rename = "incremental"))] - Incremental, -} - -impl<'i> Parse<'i> for FontTechnology { - fn parse<'t>(input: &mut Parser<'i, 't>) -> Result>> { - let location = input.current_source_location(); - match input.next()? { - Token::Ident(ident) => { - match_ignore_ascii_case! { &ident, - "variations" => Ok(FontTechnology::Variations), - "palettes" => Ok(FontTechnology::Palettes), - "incremental" => Ok(FontTechnology::Incremental), - "feature-opentype" => Ok(FontTechnology::FeatureOpentype), - "feature-aat" => Ok(FontTechnology::FeatureAat), - "feature-graphite" => Ok(FontTechnology::FeatureGraphite), - "color-colrv0" => Ok(FontTechnology::ColorCOLRv0), - "color-colrv1" => Ok(FontTechnology::ColorCOLRv1), - "color-svg" => Ok(FontTechnology::ColorSVG), - "color-sbix" => Ok(FontTechnology::ColorSbix), - "color-cbdt" => Ok(FontTechnology::ColorCBDT), - _ => Err(location.new_unexpected_token_error( - cssparser::Token::Ident(ident.clone()) - )) - } - } - tok => Err(location.new_unexpected_token_error(tok.clone())), - } - } -} - -impl ToCss for FontTechnology { - fn to_css(&self, dest: &mut Printer) -> Result<(), PrinterError> - where - W: std::fmt::Write, - { - // ref: https://hg.mozilla.org/mozilla-central/rev/f97705333d4c#l7.101 - dest.write_str(match self { - FontTechnology::FeatureOpentype => "feature-opentype", - FontTechnology::FeatureAat => "feature-aat", - FontTechnology::FeatureGraphite => "feature-graphite", - FontTechnology::ColorCOLRv0 => "color-colrv0", - FontTechnology::ColorCOLRv1 => "color-colrv1", - FontTechnology::ColorSVG => "color-svg", - FontTechnology::ColorSbix => "color-sbix", - FontTechnology::ColorCBDT => "color-cbdt", - FontTechnology::Variations => "variations", - FontTechnology::Palettes => "palettes", - FontTechnology::Incremental => "incremental", - }) + pub enum FontTechnology { + /// A font feature tech descriptor in the `tech()`function of the + /// [src](https://drafts.csswg.org/css-fonts/#font-feature-tech-values) + /// property of an `@font-face` rule. + /// Supports OpenType Features. + /// https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist + "feature-opentype": FeatureOpentype, + /// Supports Apple Advanced Typography Font Features. + /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html + "feature-aat": FeatureAat, + /// Supports Graphite Table Format. + /// https://scripts.sil.org/cms/scripts/render_download.php?site_id=nrsi&format=file&media_id=GraphiteBinaryFormat_3_0&filename=GraphiteBinaryFormat_3_0.pdf + "feature-graphite": FeatureGraphite, + + /// A color font tech descriptor in the `tech()`function of the + /// [src](https://drafts.csswg.org/css-fonts/#src-desc) + /// property of an `@font-face` rule. + /// Supports the `COLR` v0 table. + "color-colrv0": ColorCOLRv0, + /// Supports the `COLR` v1 table. + "color-colrv1": ColorCOLRv1, + /// Supports the `SVG` table. + "color-svg": ColorSVG, + /// Supports the `sbix` table. + "color-sbix": ColorSbix, + /// Supports the `CBDT` table. + "color-cbdt": ColorCBDT, + + /// Supports Variations + /// The variations tech refers to the support of font variations + "variations": Variations, + /// Supports Palettes + /// The palettes tech refers to support for font palettes + "palettes": Palettes, + /// Supports Incremental + /// The incremental tech refers to client support for incremental font loading, using either the range-request or the patch-subset method + "incremental": Incremental, } }