Skip to content

Commit

Permalink
Register font by file path URL instead.
Browse files Browse the repository at this point in the history
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(_:_:_:).
  • Loading branch information
darronschall committed Nov 15, 2023
1 parent 257adf3 commit 74acb81
Showing 1 changed file with 28 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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<CFErrorRefVar>()
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)
}
}
}

0 comments on commit 74acb81

Please sign in to comment.