9
9
#import " SDSVGImage.h"
10
10
#import " SDWebImageSVGCoderDefine.h"
11
11
#import < SVGKit/SVGKit.h>
12
+ #import < dlfcn.h>
12
13
13
14
#define kSVGTagEnd @" </svg>"
14
15
16
+ typedef struct CF_BRIDGED_TYPE (id ) CGSVGDocument *CGSVGDocumentRef;
17
+ static CGSVGDocumentRef (*CGSVGDocumentCreateFromDataProvider)(CGDataProviderRef provider, CFDictionaryRef options);
18
+ static CGSVGDocumentRef (*CGSVGDocumentRetain)(CGSVGDocumentRef);
19
+ static void (*CGSVGDocumentRelease)(CGSVGDocumentRef);
20
+
21
+ @interface UIImage (PrivateSVGSupport)
22
+
23
+ - (instancetype )_initWithCGSVGDocument : (CGSVGDocumentRef)document ;
24
+ - (instancetype )_initWithCGSVGDocument : (CGSVGDocumentRef)document scale : (double )scale orientation : (UIImageOrientation)orientation ;
25
+ + (instancetype )_imageWithCGSVGDocument : (CGSVGDocumentRef)document ;
26
+ + (instancetype )_imageWithCGSVGDocument : (CGSVGDocumentRef)document scale : (double )scale orientation : (UIImageOrientation)orientation ;
27
+ - (CGSVGDocumentRef)_CGSVGDocument ;
28
+
29
+ @end
30
+
15
31
@implementation SDImageSVGCoder
16
32
17
33
+ (SDImageSVGCoder *)sharedCoder {
@@ -23,6 +39,12 @@ + (SDImageSVGCoder *)sharedCoder {
23
39
return coder;
24
40
}
25
41
42
+ + (void )initialize {
43
+ CGSVGDocumentCreateFromDataProvider = dlsym (RTLD_DEFAULT, " CGSVGDocumentCreateFromDataProvider" );
44
+ CGSVGDocumentRetain = dlsym (RTLD_DEFAULT, " CGSVGDocumentRetain" );
45
+ CGSVGDocumentRelease = dlsym (RTLD_DEFAULT, " CGSVGDocumentRelease" );
46
+ }
47
+
26
48
#pragma mark - Decode
27
49
28
50
- (BOOL )canDecodeFromData : (NSData *)data {
@@ -33,6 +55,32 @@ - (UIImage *)decodedImageWithData:(NSData *)data options:(SDImageCoderOptions *)
33
55
if (!data) {
34
56
return nil ;
35
57
}
58
+
59
+ if ([self .class supportsVectorSVGImage ]) {
60
+ return [self createVectorSVGWithData: data options: options];
61
+ } else {
62
+ return [self createBitmapSVGWithData: data options: options];
63
+ }
64
+ }
65
+
66
+ - (UIImage *)createVectorSVGWithData : (NSData *)data options : (SDImageCoderOptions *)options {
67
+ NSParameterAssert (data);
68
+ CGDataProviderRef provider = CGDataProviderCreateWithCFData ((__bridge CFDataRef)data);
69
+ if (!provider) {
70
+ return nil ;
71
+ };
72
+ CGSVGDocumentRef document = CGSVGDocumentCreateFromDataProvider (provider, NULL );
73
+ if (!document) {
74
+ return nil ;
75
+ }
76
+ UIImage *image = [UIImage _imageWithCGSVGDocument: document];
77
+ CGSVGDocumentRelease (document);
78
+
79
+ return image;
80
+ }
81
+
82
+ - (UIImage *)createBitmapSVGWithData : (NSData *)data options : (SDImageCoderOptions *)options {
83
+ NSParameterAssert (data);
36
84
// Parse SVG
37
85
SVGKImage *svgImage = [[SVGKImage alloc ] initWithData: data];
38
86
if (!svgImage) {
@@ -99,6 +147,20 @@ - (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format o
99
147
100
148
#pragma mark - Helper
101
149
150
+ + (BOOL )supportsVectorSVGImage {
151
+ static dispatch_once_t onceToken;
152
+ static BOOL supports;
153
+ dispatch_once (&onceToken, ^{
154
+ // iOS 11+ supports PDF built-in rendering, use selector to check is more accurate
155
+ if ([UIImage respondsToSelector: @selector (_imageWithCGSVGDocument: )]) {
156
+ supports = YES ;
157
+ } else {
158
+ supports = NO ;
159
+ }
160
+ });
161
+ return supports;
162
+ }
163
+
102
164
+ (BOOL )isSVGFormatForData : (NSData *)data {
103
165
if (!data) {
104
166
return NO ;
0 commit comments