49 lines
1.9 KiB
Swift
49 lines
1.9 KiB
Swift
import ExpoModulesCore
|
|
|
|
public final class FontLoaderModule: Module {
|
|
// could be a Set, but to be able to pass to JS we keep it as an array
|
|
private lazy var registeredFonts: [String] = queryCustomNativeFonts()
|
|
|
|
public required init(appContext: AppContext) {
|
|
super.init(appContext: appContext)
|
|
}
|
|
|
|
public func definition() -> ModuleDefinition {
|
|
Name("ExpoFontLoader")
|
|
|
|
// NOTE: this is exposed in JS as globalThis.expo.modules.ExpoFontLoader.loadedFonts
|
|
// and potentially consumed outside of Expo (e.g. RN vector icons)
|
|
// do NOT change the property as it'll break consumers!
|
|
Function("getLoadedFonts") {
|
|
return registeredFonts
|
|
}
|
|
|
|
// NOTE: this is exposed in JS as globalThis.expo.modules.ExpoFontLoader.loadAsync
|
|
// and potentially consumed outside of Expo (e.g. RN vector icons)
|
|
// do NOT change the function signature as it'll break consumers!
|
|
AsyncFunction("loadAsync") { (fontFamilyAlias: String, localUri: URL) in
|
|
let fontUrl = localUri as CFURL
|
|
// If the font was already registered, unregister it first. Otherwise CTFontManagerRegisterFontsForURL
|
|
// would fail because of a duplicated font name when the app reloads or someone wants to override a font.
|
|
if FontFamilyAliasManager.familyName(forAlias: fontFamilyAlias) != nil {
|
|
guard try unregisterFont(url: fontUrl) else {
|
|
return
|
|
}
|
|
}
|
|
|
|
// Register the font
|
|
try registerFont(fontUrl: fontUrl, fontFamilyAlias: fontFamilyAlias)
|
|
|
|
// Create a font object from the given URL
|
|
let font = try loadFont(fromUrl: fontUrl, alias: fontFamilyAlias)
|
|
|
|
if let postScriptName = font.postScriptName as? String {
|
|
FontFamilyAliasManager.setAlias(fontFamilyAlias, forFont: postScriptName)
|
|
registeredFonts = Array(Set(registeredFonts).union([postScriptName, fontFamilyAlias]))
|
|
} else {
|
|
throw FontNoPostScriptException(fontFamilyAlias)
|
|
}
|
|
}
|
|
}
|
|
}
|