@@ -26,6 +26,8 @@ use alloc::{string::String, sync::Arc, vec::Vec};
2626use hashbrown:: HashMap ;
2727use read_fonts:: types:: NameId ;
2828#[ cfg( feature = "std" ) ]
29+ use std:: path:: Path ;
30+ #[ cfg( feature = "std" ) ]
2931use std:: sync:: { Mutex , atomic:: Ordering } ;
3032
3133type FamilyMap = HashMap < FamilyId , Option < FamilyInfo > > ;
@@ -83,6 +85,19 @@ impl Collection {
8385 }
8486 }
8587
88+ /// Load system fonts. If system fonts are already loaded then this does nothing.
89+ pub fn load_system_fonts ( & mut self ) {
90+ if self . inner . system . is_none ( ) {
91+ self . inner . load_system_fonts ( ) ;
92+ }
93+ }
94+
95+ /// Loads all fonts contained within the specified directory(s)
96+ #[ cfg( feature = "std" ) ]
97+ pub fn load_fonts_from_paths ( & mut self , paths : impl IntoIterator < Item = impl AsRef < Path > > ) {
98+ self . inner . load_fonts_from_paths ( paths) ;
99+ }
100+
86101 /// Returns an iterator over all available family names in the collection.
87102 ///
88103 /// If `fontique` was compiled with the `"system"` feature, then it will
@@ -239,6 +254,11 @@ impl Inner {
239254 }
240255 }
241256
257+ /// Load system fonts. If system fonts are already loaded then they will be reloaded.
258+ pub fn load_system_fonts ( & mut self ) {
259+ self . system = Some ( System :: new ( ) ) ;
260+ }
261+
242262 /// Returns an iterator over all available family names in the collection.
243263 ///
244264 /// This includes both system and registered fonts.
@@ -443,6 +463,20 @@ impl Inner {
443463 self . data . fallbacks . append ( key, families)
444464 }
445465
466+ /// Loads all fonts that exist in the specified directory(s)
467+ #[ cfg( feature = "std" ) ]
468+ pub fn load_fonts_from_paths ( & mut self , paths : impl IntoIterator < Item = impl AsRef < Path > > ) {
469+ #[ cfg( feature = "std" ) ]
470+ if let Some ( shared) = & self . shared {
471+ shared. data . lock ( ) . unwrap ( ) . load_fonts_from_paths ( paths) ;
472+ shared. bump_version ( ) ;
473+ } else {
474+ self . data . load_fonts_from_paths ( paths) ;
475+ }
476+ #[ cfg( not( feature = "std" ) ) ]
477+ self . data . register_fonts ( paths)
478+ }
479+
446480 /// Registers all fonts that exist in the given data.
447481 ///
448482 /// Returns a list of pairs each containing the family identifier and fonts
@@ -626,16 +660,64 @@ struct CommonData {
626660}
627661
628662impl CommonData {
663+ #[ cfg( feature = "std" ) ]
664+ fn load_fonts_from_paths ( & mut self , paths : impl IntoIterator < Item = impl AsRef < Path > > ) {
665+ let mut families: HashMap < FamilyId , ( FamilyName , Vec < FontInfo > ) > = HashMap :: default ( ) ;
666+ let mut scratch_family_name = String :: default ( ) ;
667+ crate :: scan:: scan_paths ( paths, 16 , |scanned_font| {
668+ let source = SourceInfo {
669+ id : SourceId :: new ( ) ,
670+ kind : SourceKind :: Path ( Arc :: from ( scanned_font. path . unwrap ( ) ) ) ,
671+ } ;
672+
673+ let font_data = scanned_font. font . data ( ) . as_bytes ( ) ;
674+ self . register_font_impl (
675+ font_data,
676+ source,
677+ None ,
678+ & mut scratch_family_name,
679+ & mut families,
680+ ) ;
681+ } ) ;
682+ }
683+
629684 fn register_fonts (
630685 & mut self ,
631686 data : Blob < u8 > ,
632687 info_override : Option < FontInfoOverride < ' _ > > ,
633688 ) -> Vec < ( FamilyId , Vec < FontInfo > ) > {
634689 let mut families: HashMap < FamilyId , ( FamilyName , Vec < FontInfo > ) > = HashMap :: default ( ) ;
635- let mut family_name = String :: default ( ) ;
636- let data_id = SourceId :: new ( ) ;
637- super :: scan:: scan_memory ( data. as_ref ( ) , |scanned_font| {
638- family_name. clear ( ) ;
690+ let mut scratch_family_name = String :: default ( ) ;
691+
692+ let source = SourceInfo {
693+ id : SourceId :: new ( ) ,
694+ kind : SourceKind :: Memory ( data. clone ( ) ) ,
695+ } ;
696+
697+ self . register_font_impl (
698+ data. as_ref ( ) ,
699+ source,
700+ info_override,
701+ & mut scratch_family_name,
702+ & mut families,
703+ ) ;
704+
705+ families
706+ . into_iter ( )
707+ . map ( |( id, ( _, fonts) ) | ( id, fonts) )
708+ . collect ( )
709+ }
710+
711+ fn register_font_impl (
712+ & mut self ,
713+ font_data : & [ u8 ] ,
714+ source : SourceInfo ,
715+ info_override : Option < FontInfoOverride < ' _ > > ,
716+ scratch_family_name : & mut String ,
717+ families : & mut HashMap < FamilyId , ( FamilyName , Vec < FontInfo > ) > ,
718+ ) {
719+ super :: scan:: scan_memory ( font_data, |scanned_font| {
720+ scratch_family_name. clear ( ) ;
639721
640722 let family_name =
641723 if let Some ( override_family_name) = info_override. and_then ( |o| o. family_name ) {
@@ -648,19 +730,18 @@ impl CommonData {
648730 let Some ( family_chars) = family_chars else {
649731 return ;
650732 } ;
651- family_name. extend ( family_chars) ;
652- & family_name
733+ scratch_family_name. extend ( family_chars) ;
734+
735+ #[ allow( clippy:: needless_borrow) ] // false positive
736+ & scratch_family_name
653737 } ;
654738
655739 if family_name. is_empty ( ) {
656740 return ;
657741 }
658- let data = SourceInfo {
659- id : data_id,
660- kind : SourceKind :: Memory ( data. clone ( ) ) ,
661- } ;
742+
662743 let Some ( mut font) =
663- FontInfo :: from_font_ref ( & scanned_font. font , data , scanned_font. index )
744+ FontInfo :: from_font_ref ( & scanned_font. font , source . clone ( ) , scanned_font. index )
664745 else {
665746 return ;
666747 } ;
@@ -669,14 +750,14 @@ impl CommonData {
669750 font. apply_override ( info_override) ;
670751 }
671752
672- let name = self . family_names . get_or_insert ( family_name ) ;
753+ let name = self . family_names . get_or_insert ( scratch_family_name ) ;
673754 families
674755 . entry ( name. id ( ) )
675756 . or_insert_with ( || ( name, Vec :: default ( ) ) )
676757 . 1
677758 . push ( font) ;
678759 } ) ;
679- for ( id, ( name, fonts) ) in & families {
760+ for ( id, ( name, fonts) ) in families. iter ( ) {
680761 if let Some ( Some ( family) ) = self . families . get_mut ( id) {
681762 let new_fonts = family. fonts ( ) . iter ( ) . chain ( fonts) . cloned ( ) ;
682763 * family = FamilyInfo :: new ( name. clone ( ) , new_fonts) ;
@@ -685,10 +766,6 @@ impl CommonData {
685766 self . families . insert ( * id, Some ( family) ) ;
686767 }
687768 }
688- families
689- . into_iter ( )
690- . map ( |( id, ( _, fonts) ) | ( id, fonts) )
691- . collect ( )
692769 }
693770
694771 fn unregister_font (
0 commit comments