1
1
use super :: { FontData , FontFamily , FontStyle , LayoutBox } ;
2
- use :: ab_glyph:: { Font , FontRef , ScaleFont } ;
3
- use :: core:: fmt:: { self , Display } ;
4
- use :: once_cell:: sync:: Lazy ;
5
- use :: std:: collections:: HashMap ;
6
- use :: std:: error:: Error ;
7
- use :: std:: sync:: RwLock ;
2
+ use ab_glyph:: { Font , FontRef , ScaleFont } ;
3
+ use core:: fmt:: { self , Display } ;
4
+ use once_cell:: sync:: Lazy ;
5
+ use std:: collections:: HashMap ;
6
+ use std:: error:: Error ;
7
+ use std:: sync:: RwLock ;
8
8
9
- static FONTS : Lazy < RwLock < HashMap < String , FontRef < ' static > > > > =
10
- Lazy :: new ( || RwLock :: new ( HashMap :: new ( ) ) ) ;
9
+ struct FontMap {
10
+ map : HashMap < String , FontRef < ' static > > ,
11
+ }
12
+ impl FontMap {
13
+ fn new ( ) -> Self {
14
+ Self {
15
+ map : HashMap :: with_capacity ( 4 ) ,
16
+ }
17
+ }
18
+ fn insert ( & mut self , style : FontStyle , font : FontRef < ' static > ) -> Option < FontRef < ' static > > {
19
+ self . map . insert ( style. as_str ( ) . to_string ( ) , font)
20
+ }
21
+ // fn get(&self, style: FontStyle) -> Option<&FontRef<'static>> {
22
+ // self.map.get(style.as_str())
23
+ // }
24
+ fn get_fallback ( & self , style : FontStyle ) -> Option < & FontRef < ' static > > {
25
+ self . map
26
+ . get ( style. as_str ( ) )
27
+ . or_else ( || self . map . get ( FontStyle :: Normal . as_str ( ) ) )
28
+ }
29
+ }
30
+
31
+ static FONTS : Lazy < RwLock < HashMap < String , FontMap > > > = Lazy :: new ( || RwLock :: new ( HashMap :: new ( ) ) ) ;
11
32
pub struct InvalidFont {
12
33
_priv : ( ) ,
13
34
}
@@ -25,10 +46,16 @@ pub struct InvalidFont {
25
46
/// ```ignore
26
47
/// include_bytes!("FiraGO-Regular.otf")
27
48
/// ```
28
- pub fn register_font ( name : & str , bytes : & ' static [ u8 ] ) -> Result < ( ) , InvalidFont > {
49
+ pub fn register_font (
50
+ name : & str ,
51
+ style : FontStyle ,
52
+ bytes : & ' static [ u8 ] ,
53
+ ) -> Result < ( ) , InvalidFont > {
29
54
let font = FontRef :: try_from_slice ( bytes) . map_err ( |_| InvalidFont { _priv : ( ) } ) ?;
30
55
let mut lock = FONTS . write ( ) . unwrap ( ) ;
31
- lock. insert ( name. to_string ( ) , font) ;
56
+ lock. entry ( name. to_string ( ) )
57
+ . or_insert_with ( || FontMap :: new ( ) )
58
+ . insert ( style, font) ;
32
59
Ok ( ( ) )
33
60
}
34
61
@@ -56,12 +83,14 @@ impl Error for FontError {}
56
83
impl FontData for FontDataInternal {
57
84
// TODO: can we rename this to `Error`?
58
85
type ErrorType = FontError ;
59
- fn new ( family : FontFamily < ' _ > , _style : FontStyle ) -> Result < Self , Self :: ErrorType > {
86
+ fn new ( family : FontFamily < ' _ > , style : FontStyle ) -> Result < Self , Self :: ErrorType > {
60
87
Ok ( Self {
61
88
font_ref : FONTS
62
89
. read ( )
63
90
. unwrap ( )
64
91
. get ( family. as_str ( ) )
92
+ . map ( |fam| fam. get_fallback ( style) )
93
+ . flatten ( )
65
94
. ok_or ( FontError :: FontUnavailable ) ?
66
95
. clone ( ) ,
67
96
} )
0 commit comments