UNPKG

6.37 kBPlain TextView Raw
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#if __has_include(<React/RCTFont.h>)
27#import <React/RCTFont.h>
28#else // Compatibility for RN version < 0.40
29#import "RCTFont.h"
30#endif
31
32NSString *const RNVIErrorDomain = @"org.oblador.react-native-vector-icons";
33
34@implementation RNVectorIconsManager
35
36@synthesize bridge = _bridge;
37RCT_EXPORT_MODULE();
38
39- (NSString *)hexStringFromColor:(UIColor *)color
40{
41 const CGFloat *components = CGColorGetComponents(color.CGColor);
42
43 CGFloat r = components[0];
44 CGFloat g = components[1];
45 CGFloat b = components[2];
46
47 return [NSString stringWithFormat:@"#%02lX%02lX%02lX",
48 lroundf(r * 255),
49 lroundf(g * 255),
50 lroundf(b * 255)];
51}
52
53- (NSString *)generateFilePath:(NSString *)glyph withFontName:(NSString *)fontName
54 withFontSize:(CGFloat)fontSize
55 withColor:(UIColor *)color
56 withExtraIdentifier:(NSString *)identifier
57{
58 CGFloat screenScale = RCTScreenScale();
59 NSString *hexColor = [self hexStringFromColor:color];
60 NSString *fileName = [NSString stringWithFormat:@"%@RNVectorIcons_%@_%@_%@_%.f%@@%.fx.png",
61 NSTemporaryDirectory(),
62 identifier, fontName, glyph,
63 fontSize, hexColor, screenScale];
64
65 return fileName;
66}
67
68- (BOOL)createAndSaveGlyphImage:(NSString *)glyph withFont:(UIFont *)font
69 withFilePath:(NSString *)filePath
70 withColor:(UIColor *)color
71{
72 if(![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
73 // No cached icon exists, we need to create it and persist to disk
74
75 NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:glyph attributes:@{NSFontAttributeName: font, NSForegroundColorAttributeName: color}];
76
77 CGSize iconSize = [attributedString size];
78 UIGraphicsBeginImageContextWithOptions(iconSize, NO, 0.0);
79 [attributedString drawAtPoint:CGPointMake(0, 0)];
80
81 UIImage *iconImage = UIGraphicsGetImageFromCurrentImageContext();
82 UIGraphicsEndImageContext();
83
84 NSData *imageData = UIImagePNGRepresentation(iconImage);
85 return [imageData writeToFile:filePath atomically:YES];
86 }
87
88 return YES;
89}
90
91- (NSString *)createGlyphImagePathForFont:(NSString *)fontName
92 withGlyph:(NSString *)glyph
93 withFontSize:(CGFloat)fontSize
94 withColor:(UIColor *)color
95 withError:(NSError **)error
96{
97 UIFont *font = [UIFont fontWithName:fontName size:fontSize];
98 NSString *filePath = [self generateFilePath:glyph withFontName:fontName
99 withFontSize:fontSize
100 withColor:color
101 withExtraIdentifier:@""];
102
103 BOOL success = [self createAndSaveGlyphImage:glyph withFont:font
104 withFilePath:filePath
105 withColor:color];
106
107 if (!success) {
108 *error = [NSError errorWithDomain:RNVIErrorDomain code:RNVIGenericError userInfo:@{NSLocalizedDescriptionKey: @"Failed to write rendered icon image"}];
109 return nil;
110 }
111 return filePath;
112}
113
114RCT_EXPORT_METHOD(
115 getImageForFont:(NSString *)fontName
116 withGlyph:(NSString *)glyph
117 withFontSize:(CGFloat)fontSize
118 withColor:(UIColor *)color
119 resolver:(RCTPromiseResolveBlock)resolve
120 rejecter:(RCTPromiseRejectBlock)reject
121) {
122 NSError *error = nil;
123 NSString *filePath = [self createGlyphImagePathForFont:fontName
124 withGlyph:glyph
125 withFontSize:fontSize
126 withColor:color
127 withError:&error];
128 if (error != nil) {
129 reject([NSString stringWithFormat:@"%ld", (long)error.code], error.localizedDescription, error);
130 } else {
131 resolve(filePath);
132 }
133}
134
135RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(
136 getImageForFontSync:(NSString *)fontName
137 withGlyph:(NSString *)glyph
138 withFontSize:(CGFloat)fontSize
139 withColor:(UIColor *)color
140) {
141 NSError *error = nil;
142 return [self createGlyphImagePathForFont:fontName
143 withGlyph:glyph
144 withFontSize:fontSize
145 withColor:color
146 withError:&error];
147}
148
149RCT_EXPORT_METHOD(
150 loadFontWithFileName:(NSString *)fontFileName
151 extension:(NSString *)extension
152 resolver:(RCTPromiseResolveBlock)resolve
153 rejecter:(RCTPromiseRejectBlock)reject
154) {
155 NSBundle *bundle = [NSBundle bundleForClass:[self class]];
156 NSURL *fontURL = [bundle URLForResource:fontFileName withExtension:extension];
157 NSData *fontData = [NSData dataWithContentsOfURL:fontURL];
158
159 CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)fontData);
160 CGFontRef font = CGFontCreateWithDataProvider(provider);
161
162 if (font) {
163 CFErrorRef errorRef = NULL;
164 if (CTFontManagerRegisterGraphicsFont(font, &errorRef) == NO) {
165 NSError *error = (__bridge NSError *)errorRef;
166 if (error.code == kCTFontManagerErrorAlreadyRegistered) {
167 resolve(nil);
168 } else {
169 reject(@"font_load_failed", @"Font failed to load", error);
170 }
171 } else {
172 resolve(nil);
173 }
174
175 CFRelease(font);
176 }
177 if (provider) {
178 CFRelease(provider);
179 }
180}
181
182@end