From 74acb81cf702422a55ea0a5d7256133dd4f303fd Mon Sep 17 00:00:00 2001 From: darronschall Date: Wed, 15 Nov 2023 11:53:13 -0500 Subject: [PATCH] Register font by file path URL instead. The documentation for `CTFontManagerRegisterGraphicsFont` at https://developer.apple.com/documentation/coretext/1499499-ctfontmanagerregistergraphicsfon hints that we should use `CTFontManagerRegisterFontsForURL` instead (since our fonts are backed by files in our bundle): > Fonts that are backed by files should be registered using CTFontManagerRegisterFontsForURL(_:_:_:). --- .../icerock/moko/resources/FontResource.kt | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/resources/src/appleMain/kotlin/dev/icerock/moko/resources/FontResource.kt b/resources/src/appleMain/kotlin/dev/icerock/moko/resources/FontResource.kt index 84dff98b..dbe10965 100644 --- a/resources/src/appleMain/kotlin/dev/icerock/moko/resources/FontResource.kt +++ b/resources/src/appleMain/kotlin/dev/icerock/moko/resources/FontResource.kt @@ -13,15 +13,22 @@ import kotlinx.cinterop.ptr import kotlinx.cinterop.value import platform.CoreFoundation.CFDataCreate import platform.CoreFoundation.CFErrorRefVar +import platform.CoreFoundation.CFRelease +import platform.CoreFoundation.CFStringRef +import platform.CoreFoundation.CFURLCreateWithFileSystemPath import platform.CoreFoundation.kCFAllocatorDefault +import platform.CoreFoundation.kCFURLPOSIXPathStyle import platform.CoreGraphics.CGDataProviderCreateWithCFData import platform.CoreGraphics.CGFontCreateWithDataProvider import platform.CoreGraphics.CGFontRef -import platform.CoreText.CTFontManagerRegisterGraphicsFont +import platform.CoreText.CTFontManagerRegisterFontsForURL +import platform.CoreText.kCTFontManagerScopeProcess import platform.Foundation.CFBridgingRelease +import platform.Foundation.CFBridgingRetain import platform.Foundation.NSBundle import platform.Foundation.NSData import platform.Foundation.NSError +import platform.Foundation.NSString import platform.Foundation.create import platform.darwin.UInt8Var @@ -59,14 +66,30 @@ actual class FontResource( @Throws(NSErrorException::class) @Suppress("unused") - fun registerFont() = + fun registerFont() { + // CAST_NEVER_SUCCEEDS - String is final and isn't castable, but on iOS it's + // an NSString so `as NSString` is fine. + // UNCHECKED_CAST - NSString and CFStringRef are toll-free bridged + @Suppress("CAST_NEVER_SUCCEEDS", "UNCHECKED_CAST") + val cfStringFilePath = CFBridgingRetain(filePath as NSString) as CFStringRef + val cfFontUrlRef = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfStringFilePath, kCFURLPOSIXPathStyle, false) + + var nsError: NSError? = null + memScoped { val error = alloc() - if (!CTFontManagerRegisterGraphicsFont(fontRef, error.ptr)) { + if (!CTFontManagerRegisterFontsForURL(cfFontUrlRef, kCTFontManagerScopeProcess, error.ptr)) { error.value?.let { - val nsError = CFBridgingRelease(it) as NSError - throw NSErrorException(nsError) + nsError = CFBridgingRelease(it) as NSError } } } + + CFRelease(cfFontUrlRef) + CFRelease(cfStringFilePath) + + nsError?.let { + throw NSErrorException(it) + } + } }