@@ -83,7 +83,7 @@ pub struct FontLibrary{
8383 fn font_collection ( & mut self ) -> FontCollection {
8484 // lazily initialize font collection on first actual use
8585 if self . collection . is_none ( ) {
86- // set up generic font family mappings
86+ // set up generic font family mappings (to be used in build_font_collection())
8787 if self . generics . is_empty ( ) {
8888 let mut generics = vec ! [ ] ;
8989 let mut font_stacks = HashMap :: new ( ) ;
@@ -115,7 +115,7 @@ pub struct FontLibrary{
115115 self . generics = generics;
116116 }
117117
118- self . rebuild_collection ( ) ; // assigns to self.collection
118+ self . collection = Some ( self . build_font_collection ( ) ) ;
119119 } ;
120120
121121 self . collection . as_ref ( ) . unwrap ( ) . clone ( )
@@ -219,10 +219,11 @@ pub struct FontLibrary{
219219
220220 // add the new typeface/alias and recreate the FontCollection to include it
221221 self . fonts . push ( ( font, alias) ) ;
222- self . rebuild_collection ( ) ;
222+ self . collection = Some ( self . build_font_collection ( ) ) ;
223+ self . collection_cache . drain ( ) ;
223224 }
224225
225- fn rebuild_collection ( & mut self ) {
226+ fn build_font_collection ( & self ) -> FontCollection {
226227 let mut assets = TypefaceFontProvider :: new ( ) ;
227228 for ( font, alias) in & self . generics {
228229 assets. register_typeface ( font. clone ( ) , alias. as_deref ( ) ) ;
@@ -240,8 +241,7 @@ pub struct FontLibrary{
240241 let mut collection = FontCollection :: new ( ) ;
241242 collection. set_default_font_manager ( self . mgr . clone ( ) , default_fam. as_deref ( ) ) ;
242243 collection. set_asset_font_manager ( Some ( assets. into ( ) ) ) ;
243- self . collection = Some ( collection) ;
244- self . collection_cache . drain ( ) ;
244+ collection
245245 }
246246
247247 pub fn update_style ( & mut self , orig_style : & TextStyle , spec : & FontSpec ) -> Option < TextStyle > {
@@ -274,32 +274,35 @@ pub struct FontLibrary{
274274 self
275275 }
276276
277- pub fn collect_fonts ( & mut self , style : & TextStyle ) -> FontCollection {
277+ pub fn fonts_for_style ( & mut self , style : & TextStyle ) -> FontCollection {
278278 let families = style. font_families ( ) ;
279279 let families: Vec < & str > = families. iter ( ) . collect ( ) ;
280280 let matches = self . font_collection ( ) . find_typefaces ( & families, style. font_style ( ) ) ;
281281
282- // if the matched typeface is a variable font, create an instance that matches
283- // the current weight settings and return early with a new FontCollection that
284- // contains just that single font instance
285- if let Some ( font) = matches. first ( ) {
286- if let Some ( params) = font. variation_design_parameters ( ) {
287-
288- // memoize the generation of single-weight FontCollections for variable fonts
289- let key = CollectionKey :: new ( style) ;
290- if let Some ( collection) = self . collection_cache . get ( & key) {
291- return collection. clone ( )
292- }
293-
294- // reconnect to the user-specified family name (if provided)
295- let alias = self . fonts . iter ( ) . find_map ( |( face, alias) |
296- if Typeface :: equal ( font, face) { alias. clone ( ) } else { None }
297- ) ;
282+ // if any of the matched typefaces is a variable font, create an instance that
283+ // matches the current weight settings and add it to a dynamic font mgr
284+ if matches. iter ( ) . any ( |font| font. variation_design_parameters ( ) . is_some ( ) ) {
285+ // memoize the generation of single-weight FontCollections for variable fonts
286+ let key = CollectionKey :: new ( style) ;
287+ if let Some ( collection) = self . collection_cache . get ( & key) {
288+ return collection. clone ( )
289+ }
298290
299- for param in params {
300- let chars = vec ! [ param. tag. a( ) , param. tag. b( ) , param. tag. c( ) , param. tag. d( ) ] ;
301- let tag = String :: from_utf8 ( chars) . unwrap ( ) ;
302- if tag == "wght" {
291+ // collect any instantiated variable fonts in a TFP to be used as the 'dynamic'
292+ // font mgr (which is searched before the 'asset' or the 'default' mgr)
293+ let mut dynamic = TypefaceFontProvider :: new ( ) ;
294+
295+ for font in matches. into_iter ( ) {
296+ font. variation_design_parameters ( )
297+ . and_then ( |params|{
298+ // find the weight axis
299+ params. into_iter ( ) . find ( |param|{
300+ let chars = vec ! [ param. tag. a( ) , param. tag. b( ) , param. tag. c( ) , param. tag. d( ) ] ;
301+ let tag = String :: from_utf8 ( chars) . unwrap ( ) ;
302+ tag == "wght"
303+ } )
304+ } ) . and_then ( |param|{
305+ // create an instance at the proper 'wght' for this weight
303306 // NB: currently setting the value to *one less* than what was requested
304307 // to work around weird Skia behavior that returns something nonlinearly
305308 // weighted in many cases (but not for ±1 of that value). This makes it so
@@ -310,25 +313,27 @@ pub struct FontLibrary{
310313 let coords = [ Coordinate { axis : param. tag , value } ] ;
311314 let v_pos = VariationPosition { coordinates : & coords } ;
312315 let args = FontArguments :: new ( ) . set_variation_design_position ( v_pos) ;
313- let face = font. clone_with_arguments ( & args) . unwrap ( ) ;
314-
315- let mut dynamic = TypefaceFontProvider :: new ( ) ;
316- dynamic. register_typeface ( face, alias. as_deref ( ) ) ;
317-
318- let mut collection = FontCollection :: new ( ) ;
319- collection. set_default_font_manager ( self . mgr . clone ( ) , None ) ;
320- collection. set_asset_font_manager ( Some ( dynamic. into ( ) ) ) ;
321- self . collection_cache . insert ( key, collection. clone ( ) ) ;
322- return collection
323- }
324- }
316+ font. clone_with_arguments ( & args)
317+ } ) . map ( |face|{
318+ // maintain the user-defined family alias (if applicable)
319+ let alias = self . fonts . iter ( ) . find_map ( |( orig, alias) |
320+ if Typeface :: equal ( & font, orig) { alias. clone ( ) } else { None }
321+ ) ;
322+
323+ // add the font to the dynamic font mgr
324+ dynamic. register_typeface ( face, alias. as_deref ( ) )
325+ } ) ;
325326 }
326- }
327327
328- // if the matched font wasn't variable, then just return the standard collection
329- self . font_collection ( )
328+ let mut collection = self . build_font_collection ( ) ;
329+ collection. set_dynamic_font_manager ( Some ( dynamic. into ( ) ) ) ;
330+ self . collection_cache . insert ( key, collection. clone ( ) ) ;
331+ collection
332+ } else {
333+ // if the matched font wasn't variable, then just return the standard collection
334+ self . font_collection ( )
335+ }
330336 }
331-
332337 }
333338
334339 //
0 commit comments