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