@@ -69,8 +69,15 @@ pub enum Source<'i> {
6969
7070impl < ' i > Parse < ' i > for Source < ' i > {
7171 fn parse < ' t > ( input : & mut Parser < ' i , ' t > ) -> Result < Self , ParseError < ' i , ParserError < ' i > > > {
72- if let Ok ( url) = input. try_parse ( UrlSource :: parse) {
73- return Ok ( Source :: Url ( url) ) ;
72+ match input. try_parse ( UrlSource :: parse) {
73+ Ok ( url) => return Ok ( Source :: Url ( url) ) ,
74+ e @ Err ( ParseError {
75+ kind : ParseErrorKind :: Basic ( BasicParseErrorKind :: AtRuleBodyInvalid ) ,
76+ ..
77+ } ) => {
78+ return Err ( e. err ( ) . unwrap ( ) ) ;
79+ }
80+ _ => { }
7481 }
7582
7683 input. expect_function_matching ( "local" ) ?;
@@ -104,20 +111,28 @@ pub struct UrlSource<'i> {
104111 pub url : Url < ' i > ,
105112 /// Optional `format()` function.
106113 #[ cfg_attr( feature = "serde" , serde( borrow) ) ]
107- pub format : Option < Format < ' i > > ,
114+ pub format : Option < FontFormat < ' i > > ,
115+ /// Optional `tech()` function.
116+ pub tech : Vec < FontTechnology > ,
108117}
109118
110119impl < ' i > Parse < ' i > for UrlSource < ' i > {
111120 fn parse < ' t > ( input : & mut Parser < ' i , ' t > ) -> Result < Self , ParseError < ' i , ParserError < ' i > > > {
112121 let url = Url :: parse ( input) ?;
113122
114123 let format = if input. try_parse ( |input| input. expect_function_matching ( "format" ) ) . is_ok ( ) {
115- Some ( input. parse_nested_block ( Format :: parse) ?)
124+ Some ( input. parse_nested_block ( FontFormat :: parse) ?)
116125 } else {
117126 None
118127 } ;
119128
120- Ok ( UrlSource { url, format } )
129+ let tech = if input. try_parse ( |input| input. expect_function_matching ( "tech" ) ) . is_ok ( ) {
130+ input. parse_nested_block ( Vec :: < FontTechnology > :: parse) ?
131+ } else {
132+ vec ! [ ]
133+ } ;
134+
135+ Ok ( UrlSource { url, format, tech } )
121136 }
122137}
123138
@@ -133,57 +148,12 @@ impl<'i> ToCss for UrlSource<'i> {
133148 format. to_css ( dest) ?;
134149 dest. write_char ( ')' ) ?;
135150 }
136- Ok ( ( ) )
137- }
138- }
139-
140- /// The `format()` function within the [src](https://drafts.csswg.org/css-fonts/#src-desc)
141- /// property of an `@font-face` rule.
142- #[ derive( Debug , Clone , PartialEq ) ]
143- #[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
144- pub struct Format < ' i > {
145- /// A font format name.
146- #[ cfg_attr( feature = "serde" , serde( borrow) ) ]
147- pub format : FontFormat < ' i > ,
148- /// The `supports()` function.
149- // TODO: did this get renamed to `tech()`?
150- pub supports : Vec < FontTechnology > ,
151- }
152151
153- impl < ' i > Parse < ' i > for Format < ' i > {
154- fn parse < ' t > ( input : & mut Parser < ' i , ' t > ) -> Result < Self , ParseError < ' i , ParserError < ' i > > > {
155- let format = FontFormat :: parse ( input) ?;
156- let mut supports = vec ! [ ] ;
157- if input. try_parse ( |input| input. expect_ident_matching ( "supports" ) ) . is_ok ( ) {
158- loop {
159- if let Ok ( technology) = input. try_parse ( FontTechnology :: parse) {
160- supports. push ( technology)
161- } else {
162- break ;
163- }
164- }
165- }
166- Ok ( Format { format, supports } )
167- }
168- }
169-
170- impl < ' i > ToCss for Format < ' i > {
171- fn to_css < W > ( & self , dest : & mut Printer < W > ) -> Result < ( ) , PrinterError >
172- where
173- W : std:: fmt:: Write ,
174- {
175- self . format . to_css ( dest) ?;
176- if !self . supports . is_empty ( ) {
177- dest. write_str ( " supports " ) ?;
178- let mut first = true ;
179- for technology in & self . supports {
180- if first {
181- first = false ;
182- } else {
183- dest. write_char ( ' ' ) ?;
184- }
185- technology. to_css ( dest) ?;
186- }
152+ if !self . tech . is_empty ( ) {
153+ dest. whitespace ( ) ?;
154+ dest. write_str ( "tech(" ) ?;
155+ self . tech . to_css ( dest) ?;
156+ dest. write_char ( ')' ) ?;
187157 }
188158 Ok ( ( ) )
189159 }
@@ -199,17 +169,18 @@ impl<'i> ToCss for Format<'i> {
199169 serde( tag = "type" , content = "value" , rename_all = "kebab-case" )
200170) ]
201171pub enum FontFormat < ' i > {
202- /// A WOFF font.
172+ /// [src](https://drafts.csswg.org/css-fonts/#font-format-definitions)
173+ /// A WOFF 1.0 font.
203174 WOFF ,
204- /// A WOFF v2 font.
175+ /// A WOFF 2.0 font.
205176 WOFF2 ,
206177 /// A TrueType font.
207178 TrueType ,
208179 /// An OpenType font.
209180 OpenType ,
210181 /// An Embedded OpenType (.eot) font.
211182 EmbeddedOpenType ,
212- /// A font collection .
183+ /// OpenType Collection .
213184 Collection ,
214185 /// An SVG font.
215186 SVG ,
@@ -258,103 +229,46 @@ impl<'i> ToCss for FontFormat<'i> {
258229}
259230
260231enum_property ! {
261- /// A font feature tech descriptor in the `supports()`function of the
262- /// [src](https://drafts.csswg.org/css-fonts/#src-desc)
263- /// property of an `@font-face` rule.
264- pub enum FontFeatureTechnology {
265- /// Supports OpenType features.
266- OpenType ,
267- /// Supports Apple Advanced Typography features.
268- AAT ,
269- /// Supports Graphite features.
270- Graphite ,
271- }
272- }
273-
274- enum_property ! {
275- /// A color font tech descriptor in the `supports()`function of the
232+ /// A font format keyword in the `format()` function of the the
276233 /// [src](https://drafts.csswg.org/css-fonts/#src-desc)
277234 /// property of an `@font-face` rule.
278- pub enum ColorFontTechnology {
235+ pub enum FontTechnology {
236+ /// A font feature tech descriptor in the `tech()`function of the
237+ /// [src](https://drafts.csswg.org/css-fonts/#font-feature-tech-values)
238+ /// property of an `@font-face` rule.
239+ /// Supports OpenType Features.
240+ /// https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
241+ "feature-opentype" : FeatureOpentype ,
242+ /// Supports Apple Advanced Typography Font Features.
243+ /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html
244+ "feature-aat" : FeatureAat ,
245+ /// Supports Graphite Table Format.
246+ /// https://scripts.sil.org/cms/scripts/render_download.php?site_id=nrsi&format=file&media_id=GraphiteBinaryFormat_3_0&filename=GraphiteBinaryFormat_3_0.pdf
247+ "feature-graphite" : FeatureGraphite ,
248+
249+ /// A color font tech descriptor in the `tech()`function of the
250+ /// [src](https://drafts.csswg.org/css-fonts/#src-desc)
251+ /// property of an `@font-face` rule.
279252 /// Supports the `COLR` v0 table.
280- COLRv0 ,
253+ "color-colrv0" : ColorCOLRv0 ,
281254 /// Supports the `COLR` v1 table.
282- COLRv1 ,
283- /// Supports SVG glyphs .
284- SVG ,
255+ "color-colrv1" : ColorCOLRv1 ,
256+ /// Supports the ` SVG` table .
257+ "color-svg" : ColorSVG ,
285258 /// Supports the `sbix` table.
286- SBIX ,
259+ "color-sbix" : ColorSbix ,
287260 /// Supports the `CBDT` table.
288- CBDT ,
289- }
290- }
291-
292- /// A font technology descriptor in the `supports()`function of the
293- /// [src](https://drafts.csswg.org/css-fonts/#src-desc)
294- /// property of an `@font-face` rule.
295- #[ derive( Debug , Clone , PartialEq ) ]
296- #[ cfg_attr(
297- feature = "serde" ,
298- derive( serde:: Serialize , serde:: Deserialize ) ,
299- serde( tag = "type" , content = "value" , rename_all = "kebab-case" )
300- ) ]
301- pub enum FontTechnology {
302- /// Supports font features.
303- Features ( FontFeatureTechnology ) ,
304- /// Supports variations.
305- Variations ,
306- /// Supports color glyphs.
307- Color ( ColorFontTechnology ) ,
308- /// Supports color palettes.
309- Palettes ,
310- }
311-
312- impl < ' i > Parse < ' i > for FontTechnology {
313- fn parse < ' t > ( input : & mut Parser < ' i , ' t > ) -> Result < Self , ParseError < ' i , ParserError < ' i > > > {
314- let location = input. current_source_location ( ) ;
315- match input. next ( ) ? {
316- Token :: Function ( f) => {
317- match_ignore_ascii_case ! { & f,
318- "features" => Ok ( FontTechnology :: Features ( input. parse_nested_block( FontFeatureTechnology :: parse) ?) ) ,
319- "color" => Ok ( FontTechnology :: Color ( input. parse_nested_block( ColorFontTechnology :: parse) ?) ) ,
320- _ => Err ( location. new_unexpected_token_error(
321- cssparser:: Token :: Ident ( f. clone( ) )
322- ) )
323- }
324- }
325- Token :: Ident ( ident) => {
326- match_ignore_ascii_case ! { & ident,
327- "variations" => Ok ( FontTechnology :: Variations ) ,
328- "palettes" => Ok ( FontTechnology :: Palettes ) ,
329- _ => Err ( location. new_unexpected_token_error(
330- cssparser:: Token :: Ident ( ident. clone( ) )
331- ) )
332- }
333- }
334- tok => Err ( location. new_unexpected_token_error ( tok. clone ( ) ) ) ,
335- }
336- }
337- }
338-
339- impl ToCss for FontTechnology {
340- fn to_css < W > ( & self , dest : & mut Printer < W > ) -> Result < ( ) , PrinterError >
341- where
342- W : std:: fmt:: Write ,
343- {
344- match self {
345- FontTechnology :: Features ( f) => {
346- dest. write_str ( "features(" ) ?;
347- f. to_css ( dest) ?;
348- dest. write_char ( ')' )
349- }
350- FontTechnology :: Color ( c) => {
351- dest. write_str ( "color(" ) ?;
352- c. to_css ( dest) ?;
353- dest. write_char ( ')' )
354- }
355- FontTechnology :: Variations => dest. write_str ( "variations" ) ,
356- FontTechnology :: Palettes => dest. write_str ( "palettes" ) ,
357- }
261+ "color-cbdt" : ColorCBDT ,
262+
263+ /// Supports Variations
264+ /// The variations tech refers to the support of font variations
265+ "variations" : Variations ,
266+ /// Supports Palettes
267+ /// The palettes tech refers to support for font palettes
268+ "palettes" : Palettes ,
269+ /// Supports Incremental
270+ /// The incremental tech refers to client support for incremental font loading, using either the range-request or the patch-subset method
271+ "incremental" : Incremental ,
358272 }
359273}
360274
0 commit comments