@@ -5,22 +5,17 @@ use super::{
5
5
scan, FallbackKey , FamilyId , FamilyInfo , FamilyNameMap , GenericFamily , GenericFamilyMap ,
6
6
} ;
7
7
use alloc:: sync:: Arc ;
8
+ use core:: ptr:: { null, null_mut} ;
8
9
use hashbrown:: HashMap ;
9
- use objc2:: runtime:: Bool ;
10
+ use objc2_core_foundation:: { CFDictionaryCreate , CFRange , CFRetained , CFString , CFStringGetLength } ;
11
+ use objc2_core_text:: {
12
+ CTFont , CTFontCopyFamilyName , CTFontCreateForString , CTFontCreateForStringWithLanguage ,
13
+ CTFontCreateUIFontForLanguage , CTFontCreateWithFontDescriptor ,
14
+ CTFontDescriptorCreateWithAttributes , CTFontUIFontType ,
15
+ } ;
10
16
use objc2_foundation:: {
11
17
NSSearchPathDirectory , NSSearchPathDomainMask , NSSearchPathForDirectoriesInDomains ,
12
18
} ;
13
- use {
14
- core_foundation:: {
15
- base:: { CFRange , TCFType } ,
16
- dictionary:: CFDictionary ,
17
- string:: { CFString , CFStringRef } ,
18
- } ,
19
- core_text:: {
20
- font:: { self , kCTFontSystemFontType, CTFont , CTFontRef , CTFontUIFontType } ,
21
- font_descriptor,
22
- } ,
23
- } ;
24
19
25
20
const DEFAULT_GENERIC_FAMILIES : & [ ( GenericFamily , & [ & str ] ) ] = & [
26
21
( GenericFamily :: Serif , & [ "Times" , "Times New Roman" ] ) ,
@@ -43,12 +38,11 @@ impl SystemFonts {
43
38
pub ( crate ) fn new ( ) -> Self {
44
39
let paths = unsafe {
45
40
NSSearchPathForDirectoriesInDomains (
46
- NSSearchPathDirectory :: NSLibraryDirectory ,
47
- NSSearchPathDomainMask :: NSAllDomainsMask ,
48
- Bool :: YES ,
41
+ NSSearchPathDirectory :: LibraryDirectory ,
42
+ NSSearchPathDomainMask :: AllDomainsMask ,
43
+ true ,
49
44
)
50
- . as_ref ( )
51
- . iter ( )
45
+ . into_iter ( )
52
46
. map ( |p| format ! ( "{p}/Fonts/" ) )
53
47
} ;
54
48
let scanned = scan:: ScannedCollection :: from_paths ( paths, 8 ) ;
@@ -77,97 +71,39 @@ impl SystemFonts {
77
71
pub ( crate ) fn fallback ( & mut self , key : impl Into < FallbackKey > ) -> Option < FamilyId > {
78
72
let key = key. into ( ) ;
79
73
let sample = key. script ( ) . sample ( ) ?;
80
- self . fallback_for_text ( sample, key. locale ( ) , false )
74
+ let font = self . fallback_font_for_text ( sample, key. locale ( ) , false ) ?;
75
+ let family_name = unsafe { CTFontCopyFamilyName ( & font) } ;
76
+ self . name_map . get ( & family_name. to_string ( ) ) . map ( |n| n. id ( ) )
81
77
}
82
- }
83
78
84
- impl SystemFonts {
85
- fn fallback_for_text (
79
+ fn fallback_font_for_text (
86
80
& mut self ,
87
81
text : & str ,
88
82
locale : Option < & str > ,
89
83
prefer_ui : bool ,
90
- ) -> Option < FamilyId > {
91
- let font = fallback_for_text ( text, locale, prefer_ui) ?;
92
- self . name_map . get ( & font. family_name ( ) ) . map ( |n| n. id ( ) )
93
- }
94
- }
95
-
96
- fn fallback_for_text ( text : & str , locale : Option < & str > , prefer_ui : bool ) -> Option < CTFont > {
97
- let cf_text = CFString :: new ( text) ;
98
- let cf_text_range = CFRange :: init ( 0 , cf_text. char_len ( ) ) ;
99
- let cf_locale = locale. map ( CFString :: new) ;
100
- let base_font = {
101
- let desc_attrs = CFDictionary :: from_CFType_pairs ( & [ ] ) ;
102
- let mut desc = font_descriptor:: new_from_attributes ( & desc_attrs) ;
103
- if prefer_ui {
104
- if let Some ( ui_desc) = ui_font_for_language ( kCTFontSystemFontType, 0.0 , None )
105
- . map ( |font| font. copy_descriptor ( ) )
106
- {
107
- desc = ui_desc;
108
- }
109
- }
110
- font:: new_from_descriptor ( & desc, 0.0 )
111
- } ;
112
- let font = unsafe {
113
- CTFont :: wrap_under_create_rule ( if let Some ( locale) = cf_locale {
114
- CTFontCreateForStringWithLanguage (
115
- base_font. as_concrete_TypeRef ( ) ,
116
- cf_text. as_concrete_TypeRef ( ) ,
117
- cf_text_range,
118
- locale. as_concrete_TypeRef ( ) ,
119
- )
120
- } else {
121
- CTFontCreateForString (
122
- base_font. as_concrete_TypeRef ( ) ,
123
- cf_text. as_concrete_TypeRef ( ) ,
124
- cf_text_range,
125
- )
126
- } )
127
- } ;
128
- Some ( font)
129
- }
130
-
131
- fn ui_font_for_language (
132
- ui_type : CTFontUIFontType ,
133
- size : f64 ,
134
- language : Option < CFString > ,
135
- ) -> Option < CTFont > {
136
- unsafe {
137
- let font_ref = CTFontCreateUIFontForLanguage (
138
- ui_type,
139
- size,
140
- language
141
- . as_ref ( )
142
- . map ( |x| x. as_concrete_TypeRef ( ) )
143
- . unwrap_or ( std:: ptr:: null ( ) ) ,
144
- ) ;
145
- if font_ref. is_null ( ) {
146
- None
84
+ ) -> Option < CFRetained < CTFont > > {
85
+ let text = CFString :: from_str ( text) ;
86
+ let text_range = CFRange {
87
+ location : 0 ,
88
+ length : unsafe { CFStringGetLength ( & text) } ,
89
+ } ;
90
+ let locale = locale. map ( CFString :: from_str) ;
91
+ let base_font = if prefer_ui {
92
+ unsafe { CTFontCreateUIFontForLanguage ( CTFontUIFontType :: System , 0.0 , None ) . unwrap ( ) }
147
93
} else {
148
- Some ( CTFont :: wrap_under_create_rule ( font_ref) )
149
- }
94
+ unsafe {
95
+ let attrs = CFDictionaryCreate ( None , null_mut ( ) , null_mut ( ) , 0 , null ( ) , null ( ) ) ;
96
+ let desc = CTFontDescriptorCreateWithAttributes ( & attrs. unwrap ( ) ) ;
97
+ CTFontCreateWithFontDescriptor ( & desc, 0.0 , null ( ) )
98
+ }
99
+ } ;
100
+ let font = unsafe {
101
+ if let Some ( locale) = locale {
102
+ CTFontCreateForStringWithLanguage ( & base_font, & text, text_range, Some ( & locale) )
103
+ } else {
104
+ CTFontCreateForString ( & base_font, & text, text_range)
105
+ }
106
+ } ;
107
+ Some ( font)
150
108
}
151
109
}
152
-
153
- #[ link( name = "CoreText" , kind = "framework" ) ]
154
- extern "C" {
155
- fn CTFontCreateUIFontForLanguage (
156
- uiType : CTFontUIFontType ,
157
- size : f64 ,
158
- language : CFStringRef ,
159
- ) -> CTFontRef ;
160
-
161
- fn CTFontCreateForString (
162
- currentFont : CTFontRef ,
163
- string : CFStringRef ,
164
- range : CFRange ,
165
- ) -> CTFontRef ;
166
-
167
- fn CTFontCreateForStringWithLanguage (
168
- currentFont : CTFontRef ,
169
- string : CFStringRef ,
170
- range : CFRange ,
171
- language : CFStringRef ,
172
- ) -> CTFontRef ;
173
- }
0 commit comments