11//! Font rendering based on CoreText.
22
33use std:: collections:: HashMap ;
4- use std:: ffi:: c_char;
54use std:: ffi:: CStr ;
65use std:: iter;
76use std:: path:: PathBuf ;
87use std:: ptr;
98
10- use cocoa:: base:: { id, nil} ;
11- use cocoa:: foundation:: { NSInteger , NSString , NSUserDefaults } ;
12-
139use core_foundation:: array:: { CFArray , CFIndex } ;
1410use core_foundation:: base:: { CFType , ItemRef , TCFType } ;
1511use core_foundation:: number:: { CFNumber , CFNumberRef } ;
@@ -28,10 +24,10 @@ use core_text::font_descriptor::{
2824 self , kCTFontColorGlyphsTrait, kCTFontDefaultOrientation, kCTFontEnabledAttribute,
2925 CTFontDescriptor , SymbolicTraitAccessors ,
3026} ;
27+ use objc2:: rc:: { autoreleasepool, Retained } ;
28+ use objc2_foundation:: { ns_string, NSNumber , NSObject , NSObjectProtocol , NSString , NSUserDefaults } ;
3129
3230use log:: { trace, warn} ;
33- use objc:: rc:: autoreleasepool;
34- use objc:: { class, msg_send, sel, sel_impl} ;
3531use once_cell:: sync:: Lazy ;
3632
3733pub mod byte_order;
@@ -274,30 +270,40 @@ fn descriptors_for_family(family: &str) -> Vec<Descriptor> {
274270// other integer, or a missing value (the default), or a value of any other type, as leaving it
275271// enabled.
276272static 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+ } ;
280280
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) } ;
286288
287289 // NSNumber's objCType method returns one of these strings depending on the size:
288290 // q = quad (long long), l = long, i = int, s = short.
289291 // This is done to reject booleans, which are NSNumbers with an objCType of "c", but
290292 // macOS does not treat them the same as an integer 0 or 1 for this setting,
291293 // it just ignores it.
292294 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) {
294298 return true ;
295299 }
296300
297- let smoothing: NSInteger = msg_send ! [ value, integerValue] ;
301+ let smoothing = value. integerValue ( ) ;
298302 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 ( ) } ;
301307 smoothing != 0
302308 } else {
303309 true
0 commit comments