@@ -130,6 +130,16 @@ impl<'a> FontFallbackIter<'a> {
130
130
false
131
131
}
132
132
}
133
+
134
+ fn default_font_match_key ( & self ) -> Option < & FontMatchKey > {
135
+ let default_family = self . default_families [ self . default_i - 1 ] ;
136
+ let default_family_name = self . font_system . db ( ) . family_name ( default_family) ;
137
+
138
+ self . font_match_keys
139
+ . iter ( )
140
+ . filter ( |m_key| m_key. font_weight_diff == 0 )
141
+ . find ( |m_key| self . face_contains_family ( m_key. id , default_family_name) )
142
+ }
133
143
}
134
144
135
145
impl < ' a > Iterator for FontFallbackIter < ' a > {
@@ -147,9 +157,58 @@ impl<'a> Iterator for FontFallbackIter<'a> {
147
157
. filter ( move |m_key| m_key. font_weight_diff == 0 || is_mono)
148
158
} ;
149
159
150
- while self . default_i < self . default_families . len ( ) {
160
+ ' DEF_FAM : while self . default_i < self . default_families . len ( ) {
151
161
self . default_i += 1 ;
152
162
let is_mono = self . default_families [ self . default_i - 1 ] == & Family :: Monospace ;
163
+ let default_font_match_key = self . default_font_match_key ( ) . cloned ( ) ;
164
+ let word_chars_count = self . word . chars ( ) . count ( ) ;
165
+
166
+ macro_rules! mk_mono_fallback_info {
167
+ ( $m_key: expr) => { {
168
+ let supported_cp_count_opt = self
169
+ . font_system
170
+ . get_font_supported_codepoints_in_word( $m_key. id, self . word) ;
171
+
172
+ supported_cp_count_opt. map( |supported_cp_count| {
173
+ let codepoint_non_matches = word_chars_count - supported_cp_count;
174
+
175
+ MonospaceFallbackInfo {
176
+ font_weight_diff: Some ( $m_key. font_weight_diff) ,
177
+ codepoint_non_matches: Some ( codepoint_non_matches) ,
178
+ font_weight: $m_key. font_weight,
179
+ id: $m_key. id,
180
+ }
181
+ } )
182
+ } } ;
183
+ }
184
+
185
+ match ( is_mono, default_font_match_key. as_ref ( ) ) {
186
+ ( false , None ) => break ' DEF_FAM ,
187
+ ( false , Some ( m_key) ) => {
188
+ if let Some ( font) = self . font_system . get_font ( m_key. id ) {
189
+ return Some ( font) ;
190
+ } else {
191
+ break ' DEF_FAM ;
192
+ }
193
+ }
194
+ ( true , None ) => ( ) ,
195
+ ( true , Some ( m_key) ) => {
196
+ // Default Monospace font
197
+ if let Some ( mut fallback_info) = mk_mono_fallback_info ! ( m_key) {
198
+ fallback_info. font_weight_diff = None ;
199
+
200
+ // Return early if default Monospace font supports all word codepoints.
201
+ // Otherewise, add to fallbacks set
202
+ if fallback_info. codepoint_non_matches == Some ( 0 ) {
203
+ if let Some ( font) = self . font_system . get_font ( m_key. id ) {
204
+ return Some ( font) ;
205
+ }
206
+ } else {
207
+ assert ! ( self . monospace_fallbacks. insert( fallback_info) ) ;
208
+ }
209
+ }
210
+ }
211
+ } ;
153
212
154
213
let mono_ids_for_scripts = if is_mono && !self . scripts . is_empty ( ) {
155
214
let scripts = self . scripts . iter ( ) . filter_map ( |script| {
@@ -162,35 +221,14 @@ impl<'a> Iterator for FontFallbackIter<'a> {
162
221
} ;
163
222
164
223
for m_key in font_match_keys_iter ( is_mono) {
165
- let default_family = self
166
- . font_system
167
- . db ( )
168
- . family_name ( self . default_families [ self . default_i - 1 ] ) ;
169
- if self . face_contains_family ( m_key. id , default_family) {
170
- if let Some ( font) = self . font_system . get_font ( m_key. id ) {
171
- if !is_mono {
172
- return Some ( font) ;
173
- } else if m_key. font_weight_diff == 0 {
174
- // Default font
175
- let fallback_info = MonospaceFallbackInfo {
176
- font_weight_diff : None ,
177
- codepoint_non_matches : None ,
178
- font_weight : m_key. font_weight ,
179
- id : m_key. id ,
180
- } ;
181
- assert ! ( self . monospace_fallbacks. insert( fallback_info) ) ;
182
- }
183
- }
184
- }
185
- // Set a monospace fallback if Monospace family is not found
186
- if is_mono {
187
- let include_mono_id = if mono_ids_for_scripts. is_empty ( ) {
224
+ if Some ( m_key. id ) != default_font_match_key. as_ref ( ) . map ( |m_key| m_key. id ) {
225
+ let is_mono_id = if mono_ids_for_scripts. is_empty ( ) {
188
226
self . font_system . is_monospace ( m_key. id )
189
227
} else {
190
228
mono_ids_for_scripts. binary_search ( & m_key. id ) . is_ok ( )
191
229
} ;
192
230
193
- if include_mono_id {
231
+ if is_mono_id {
194
232
let supported_cp_count_opt = self
195
233
. font_system
196
234
. get_font_supported_codepoints_in_word ( m_key. id , self . word ) ;
0 commit comments