1
1
//! Font rendering based on CoreText.
2
2
3
3
use std:: collections:: HashMap ;
4
- use std:: ffi:: c_char;
5
4
use std:: ffi:: CStr ;
6
5
use std:: iter;
7
6
use std:: path:: PathBuf ;
8
7
use std:: ptr;
9
8
10
- use cocoa:: base:: { id, nil} ;
11
- use cocoa:: foundation:: { NSInteger , NSString , NSUserDefaults } ;
12
-
13
9
use core_foundation:: array:: { CFArray , CFIndex } ;
14
10
use core_foundation:: base:: { CFType , ItemRef , TCFType } ;
15
11
use core_foundation:: number:: { CFNumber , CFNumberRef } ;
@@ -28,10 +24,10 @@ use core_text::font_descriptor::{
28
24
self , kCTFontColorGlyphsTrait, kCTFontDefaultOrientation, kCTFontEnabledAttribute,
29
25
CTFontDescriptor , SymbolicTraitAccessors ,
30
26
} ;
27
+ use objc2:: rc:: { autoreleasepool, Retained } ;
28
+ use objc2_foundation:: { ns_string, NSNumber , NSObject , NSObjectProtocol , NSString , NSUserDefaults } ;
31
29
32
30
use log:: { trace, warn} ;
33
- use objc:: rc:: autoreleasepool;
34
- use objc:: { class, msg_send, sel, sel_impl} ;
35
31
use once_cell:: sync:: Lazy ;
36
32
37
33
pub mod byte_order;
@@ -274,30 +270,40 @@ fn descriptors_for_family(family: &str) -> Vec<Descriptor> {
274
270
// other integer, or a missing value (the default), or a value of any other type, as leaving it
275
271
// enabled.
276
272
static FONT_SMOOTHING_ENABLED : Lazy < bool > = Lazy :: new ( || {
277
- autoreleasepool ( || unsafe {
278
- let key = NSString :: alloc ( nil) . init_str ( "AppleFontSmoothing" ) ;
279
- let value: id = msg_send ! [ id:: standardUserDefaults( ) , objectForKey: key] ;
273
+ autoreleasepool ( |_| {
274
+ let value = unsafe {
275
+ NSUserDefaults :: standardUserDefaults ( ) . objectForKey ( ns_string ! ( "AppleFontSmoothing" ) )
276
+ } ;
277
+ let Some ( value) = value else {
278
+ return true ;
279
+ } ;
280
280
281
- if msg_send ! [ value, isKindOfClass: class!( NSNumber ) ] {
282
- let num_type: * const c_char = msg_send ! [ value, objCType] ;
283
- if num_type. is_null ( ) {
284
- return true ;
285
- }
281
+ // SAFETY: The values in `NSUserDefaults` are always subclasses of
282
+ // `NSObject`.
283
+ let value: Retained < NSObject > = unsafe { Retained :: cast ( value) } ;
284
+
285
+ if value. is_kind_of :: < NSNumber > ( ) {
286
+ // SAFETY: Just checked that the value is a NSNumber
287
+ let value: Retained < NSNumber > = unsafe { Retained :: cast ( value) } ;
286
288
287
289
// NSNumber's objCType method returns one of these strings depending on the size:
288
290
// q = quad (long long), l = long, i = int, s = short.
289
291
// This is done to reject booleans, which are NSNumbers with an objCType of "c", but
290
292
// macOS does not treat them the same as an integer 0 or 1 for this setting,
291
293
// it just ignores it.
292
294
let int_specifiers: [ & [ u8 ] ; 4 ] = [ b"q" , b"l" , b"i" , b"s" ] ;
293
- if !int_specifiers. contains ( & CStr :: from_ptr ( num_type) . to_bytes ( ) ) {
295
+
296
+ let encoding = unsafe { CStr :: from_ptr ( value. objCType ( ) . as_ptr ( ) ) . to_bytes ( ) } ;
297
+ if !int_specifiers. contains ( & encoding) {
294
298
return true ;
295
299
}
296
300
297
- let smoothing: NSInteger = msg_send ! [ value, integerValue] ;
301
+ let smoothing = value. integerValue ( ) ;
298
302
smoothing != 0
299
- } else if msg_send ! [ value, isKindOfClass: class!( NSString ) ] {
300
- let smoothing: NSInteger = msg_send ! [ value, integerValue] ;
303
+ } else if value. is_kind_of :: < NSString > ( ) {
304
+ // SAFETY: Just checked that the value is a NSString
305
+ let value: Retained < NSString > = unsafe { Retained :: cast ( value) } ;
306
+ let smoothing = unsafe { value. integerValue ( ) } ;
301
307
smoothing != 0
302
308
} else {
303
309
true
0 commit comments