1 | //
|
2 | // RNVectorIconsManager.m
|
3 | // RNVectorIconsManager
|
4 | //
|
5 | // Created by Joel Arvidsson on 2015-05-29.
|
6 | // Copyright (c) 2015 Joel Arvidsson. All rights reserved.
|
7 | //
|
8 |
|
9 | #import "RNVectorIconsManager.h"
|
10 | #import <CoreText/CoreText.h>
|
11 | #if __has_include(<React/RCTConvert.h>)
|
12 | #import <React/RCTConvert.h>
|
13 | #else // Compatibility for RN version < 0.40
|
14 | #import "RCTConvert.h"
|
15 | #endif
|
16 | #if __has_include(<React/RCTBridge.h>)
|
17 | #import <React/RCTBridge.h>
|
18 | #else // Compatibility for RN version < 0.40
|
19 | #import "RCTBridge.h"
|
20 | #endif
|
21 | #if __has_include(<React/RCTUtils.h>)
|
22 | #import <React/RCTUtils.h>
|
23 | #else // Compatibility for RN version < 0.40
|
24 | #import "RCTUtils.h"
|
25 | #endif
|
26 |
|
27 | @implementation RNVectorIconsManager
|
28 |
|
29 | @synthesize bridge = _bridge;
|
30 | RCT_EXPORT_MODULE();
|
31 |
|
32 | - (NSString *)hexStringFromColor:(UIColor *)color {
|
33 | const CGFloat *components = CGColorGetComponents(color.CGColor);
|
34 |
|
35 | CGFloat r = components[0];
|
36 | CGFloat g = components[1];
|
37 | CGFloat b = components[2];
|
38 |
|
39 | return [NSString stringWithFormat:@"#%02lX%02lX%02lX",
|
40 | lroundf(r * 255),
|
41 | lroundf(g * 255),
|
42 | lroundf(b * 255)];
|
43 | }
|
44 |
|
45 |
|
46 | RCT_EXPORT_METHOD(getImageForFont:(NSString*)fontName withGlyph:(NSString*)glyph withFontSize:(CGFloat)fontSize withColor:(UIColor *)color callback:(RCTResponseSenderBlock)callback){
|
47 | CGFloat screenScale = RCTScreenScale();
|
48 |
|
49 | NSString *hexColor = [self hexStringFromColor:color];
|
50 |
|
51 | NSString *fileName = [NSString stringWithFormat:@"tmp/RNVectorIcons_%@_%hu_%.f%@@%.fx.png", fontName, [glyph characterAtIndex:0], fontSize, hexColor, screenScale];
|
52 | NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:fileName];
|
53 |
|
54 | if(![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
|
55 | // No cached icon exists, we need to create it and persist to disk
|
56 |
|
57 | UIFont *font = [UIFont fontWithName:fontName size:fontSize];
|
58 | NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:glyph attributes:@{NSFontAttributeName: font, NSForegroundColorAttributeName: color}];
|
59 |
|
60 | CGSize iconSize = [attributedString size];
|
61 | UIGraphicsBeginImageContextWithOptions(iconSize, NO, 0.0);
|
62 | [attributedString drawAtPoint:CGPointMake(0, 0)];
|
63 |
|
64 | UIImage *iconImage = UIGraphicsGetImageFromCurrentImageContext();
|
65 | UIGraphicsEndImageContext();
|
66 |
|
67 | NSData *imageData = UIImagePNGRepresentation(iconImage);
|
68 | BOOL success = [imageData writeToFile:filePath atomically:YES];
|
69 | if(!success) {
|
70 | return callback(@[@"Failed to write rendered icon image"]);
|
71 | }
|
72 | }
|
73 | callback(@[[NSNull null], filePath]);
|
74 | }
|
75 |
|
76 | RCT_EXPORT_METHOD(loadFontWithFileName:(NSString *)fontFileName
|
77 | extension:(NSString *)extension
|
78 | resolver:(RCTPromiseResolveBlock)resolve
|
79 | rejecter:(RCTPromiseRejectBlock)reject)
|
80 | {
|
81 | NSBundle *bundle = [NSBundle bundleForClass:[self class]];
|
82 | NSURL *fontURL = [bundle URLForResource:fontFileName withExtension:extension];
|
83 | NSData *fontData = [NSData dataWithContentsOfURL:fontURL];
|
84 |
|
85 | CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)fontData);
|
86 | CGFontRef font = CGFontCreateWithDataProvider(provider);
|
87 |
|
88 | if (font) {
|
89 | CFErrorRef errorRef = NULL;
|
90 | if (CTFontManagerRegisterGraphicsFont(font, &errorRef) == NO) {
|
91 | NSError *error = (__bridge NSError *)errorRef;
|
92 | if (error.code == kCTFontManagerErrorAlreadyRegistered) {
|
93 | resolve(nil);
|
94 | } else {
|
95 | reject(@"font_load_failed", @"Font failed to load", error);
|
96 | }
|
97 | } else {
|
98 | resolve(nil);
|
99 | }
|
100 |
|
101 | CFRelease(font);
|
102 | }
|
103 | if (provider) {
|
104 | CFRelease(provider);
|
105 | }
|
106 | }
|
107 |
|
108 | @end
|