1
1
use std:: cell:: RefCell ;
2
2
use std:: collections:: BinaryHeap ;
3
+ use std:: path:: Path ;
3
4
4
5
use anyhow:: Context ;
5
6
use fontdue:: layout:: { CoordinateSystem , Layout , LayoutSettings , TextStyle , VerticalAlign } ;
@@ -10,35 +11,27 @@ use rust_fontconfig::{FcFontCache, FcFontPath, FcPattern};
10
11
11
12
use super :: { FontBackend , FontColor , Result } ;
12
13
13
- static FONTCONFIG : Lazy < FontConfig > = Lazy :: new ( FontConfig :: new ) ;
14
+ static FONTCONFIG_CACHE : Lazy < FcFontCache > = Lazy :: new ( FcFontCache :: build ) ;
14
15
const BUF_SIZE : usize = 256 * 256 ;
15
16
16
17
pub struct Font {
17
18
inner : fontdue:: Font ,
18
- }
19
-
20
- // Because Font is re-created on every `draw` call method we cached dynamic allocations
21
- struct FontConfig {
22
- cache : FcFontCache ,
23
19
// Layout in fontdue uses allocations, so we're reusing it for reduce memory allocations
24
20
layout : RefCell < Layout > ,
25
21
// Move buffer to heap, because it is very big for stack; only one allocation happens
26
22
buffer : RefCell < Vec < u32 > > ,
27
23
}
28
24
29
- impl FontConfig {
30
- fn new ( ) -> Self {
25
+ impl Font {
26
+ fn with_font ( inner : fontdue :: Font ) -> Self {
31
27
Self {
32
- cache : FcFontCache :: build ( ) ,
28
+ inner ,
33
29
layout : RefCell :: new ( Layout :: new ( CoordinateSystem :: PositiveYDown ) ) ,
34
30
buffer : RefCell :: new ( vec ! [ 0 ; BUF_SIZE ] ) ,
35
31
}
36
32
}
37
33
}
38
34
39
- //SAFETY: We do not use multiple threads, so it never happens that the & is posted to another thread
40
- unsafe impl Sync for FontConfig { }
41
-
42
35
#[ derive( Eq ) ]
43
36
struct FuzzyResult < ' a > {
44
37
text : & ' a str ,
@@ -75,14 +68,13 @@ impl Font {
75
68
)
76
69
. map_err ( |e| anyhow:: anyhow!( "{}" , e) ) ?;
77
70
78
- Ok ( Font { inner } )
71
+ Ok ( Font :: with_font ( inner) )
79
72
}
80
73
81
74
fn try_find_best_font ( name : & str ) -> Vec < String > {
82
75
const COUNT_MATCHES : usize = 5 ;
83
76
84
- FONTCONFIG
85
- . cache
77
+ FONTCONFIG_CACHE
86
78
. list ( )
87
79
. keys ( )
88
80
. filter_map ( |font| {
@@ -103,17 +95,15 @@ impl Font {
103
95
104
96
impl FontBackend for Font {
105
97
fn default ( ) -> Self {
106
- FONTCONFIG
107
- . cache
98
+ FONTCONFIG_CACHE
108
99
. query ( & FcPattern :: default ( ) )
109
100
. map ( Font :: from_fc_path)
110
101
. unwrap ( )
111
102
. unwrap ( )
112
103
}
113
104
114
105
fn font_by_name ( name : & str ) -> Result < Self > {
115
- FONTCONFIG
116
- . cache
106
+ FONTCONFIG_CACHE
117
107
. query ( & FcPattern {
118
108
name : Some ( name. to_string ( ) ) ,
119
109
..Default :: default ( )
@@ -130,6 +120,16 @@ impl FontBackend for Font {
130
120
} ) ?
131
121
}
132
122
123
+ fn font_by_path ( path : & Path ) -> Result < Self > {
124
+ Font :: from_fc_path ( & FcFontPath {
125
+ path : path
126
+ . to_str ( )
127
+ . ok_or_else ( || anyhow:: anyhow!( "Invalid path" ) ) ?
128
+ . to_owned ( ) ,
129
+ font_index : 0 ,
130
+ } )
131
+ }
132
+
133
133
fn draw (
134
134
& self ,
135
135
dt : & mut DrawTarget ,
@@ -139,8 +139,8 @@ impl FontBackend for Font {
139
139
color : FontColor ,
140
140
opts : & DrawOptions ,
141
141
) {
142
- let mut buf = FONTCONFIG . buffer . borrow_mut ( ) ;
143
- let mut layout = FONTCONFIG . layout . borrow_mut ( ) ;
142
+ let mut buf = self . buffer . borrow_mut ( ) ;
143
+ let mut layout = self . layout . borrow_mut ( ) ;
144
144
145
145
layout. reset ( & LayoutSettings {
146
146
x : start_pos. x ,
0 commit comments