1// Copyright 2015-present 650 Industries. All rights reserved. 2 3#import <EXFont/EXFontLoader.h> 4#import <EXFont/EXFontLoaderProcessor.h> 5#import <ExpoModulesCore/EXFontManagerInterface.h> 6#import <ExpoModulesCore/EXFontScalersManagerInterface.h> 7#import <EXFont/EXFontScaler.h> 8#import <EXFont/EXFont.h> 9#import <objc/runtime.h> 10#import <EXFont/EXFontManager.h> 11#import <EXFont/EXFontScalersManager.h> 12 13@interface EXFontLoader () 14 15@property (nonatomic, strong) EXFontScaler *scaler; 16@property (nonatomic, strong) EXFontLoaderProcessor *processor; 17@property (nonatomic, strong) EXFontManager *manager; 18 19@end 20 21@implementation EXFontLoader 22 23EX_EXPORT_MODULE(ExpoFontLoader); 24 25- (instancetype)init 26{ 27 if (self = [super init]) { 28 _scaler = [[EXFontScaler alloc] init]; 29 _manager = [[EXFontManager alloc] init]; 30 _processor = [[EXFontLoaderProcessor alloc] initWithManager:_manager]; 31 } 32 return self; 33} 34 35- (instancetype)initWithFontFamilyPrefix:(NSString *)prefix 36{ 37 if (self = [super init]) { 38 _scaler = [[EXFontScaler alloc] init]; 39 _manager = [[EXFontManager alloc] init]; 40 _processor = [[EXFontLoaderProcessor alloc] initWithFontFamilyPrefix:prefix manager:_manager]; 41 } 42 return self; 43} 44 45 46- (void)setModuleRegistry:(EXModuleRegistry *)moduleRegistry 47{ 48 if (moduleRegistry) { 49 id<EXFontManagerInterface> manager = [moduleRegistry getModuleImplementingProtocol:@protocol(EXFontManagerInterface)]; 50 [manager addFontProcessor:_processor]; 51 52 id<EXFontScalersManagerInterface> scalersManager = [moduleRegistry getSingletonModuleForName:@"FontScalersManager"]; 53 [scalersManager registerFontScaler:_scaler]; 54 } 55} 56 57EX_EXPORT_METHOD_AS(loadAsync, 58 loadAsyncWithFontFamilyName:(NSString *)fontFamilyName 59 withLocalUri:(NSString *)path 60 resolver:(EXPromiseResolveBlock)resolve 61 rejecter:(EXPromiseRejectBlock)reject) 62{ 63 if ([_manager fontForName:fontFamilyName]) { 64 reject(@"E_FONT_ALREADY_EXISTS", 65 [NSString stringWithFormat:@"Font with family name '%@' already loaded", fontFamilyName], 66 nil); 67 return; 68 } 69 70 // TODO(nikki): make sure path is in experience's scope 71 NSURL *uriString = [[NSURL alloc] initWithString:path]; 72 NSData *data = [[NSFileManager defaultManager] contentsAtPath:[uriString path]]; 73 if (!data) { 74 reject(@"E_FONT_FILE_NOT_FOUND", 75 [NSString stringWithFormat:@"File '%@' for font '%@' doesn't exist", path, fontFamilyName], 76 nil); 77 return; 78 } 79 80 CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); 81 CGFontRef font = CGFontCreateWithDataProvider(provider); 82 CGDataProviderRelease(provider); 83 if (!font) { 84 reject(@"E_FONT_CREATION_FAILED", 85 [NSString stringWithFormat:@"Could not create font from loaded data for '%@'", fontFamilyName], 86 nil); 87 return; 88 } 89 90 [_manager setFont:[[EXFont alloc] initWithCGFont:font] forName:fontFamilyName]; 91 resolve(nil); 92} 93 94@end 95