13
13
#define kSVGTagEnd @" </svg>"
14
14
15
15
typedef struct CF_BRIDGED_TYPE (id ) CGSVGDocument *CGSVGDocumentRef;
16
- static CGSVGDocumentRef (*CGSVGDocumentRetain )(CGSVGDocumentRef);
17
- static void (*CGSVGDocumentRelease )(CGSVGDocumentRef);
18
- static CGSVGDocumentRef (*CGSVGDocumentCreateFromData )(CFDataRef data, CFDictionaryRef options);
19
- static void (*CGSVGDocumentWriteToData )(CGSVGDocumentRef document, CFDataRef data, CFDictionaryRef options);
20
- static void (*CGContextDrawSVGDocument )(CGContextRef context, CGSVGDocumentRef document);
21
- static CGSize (*CGSVGDocumentGetCanvasSize )(CGSVGDocumentRef document);
16
+ static CGSVGDocumentRef (*SDCGSVGDocumentRetain )(CGSVGDocumentRef);
17
+ static void (*SDCGSVGDocumentRelease )(CGSVGDocumentRef);
18
+ static CGSVGDocumentRef (*SDCGSVGDocumentCreateFromData )(CFDataRef data, CFDictionaryRef options);
19
+ static void (*SDCGSVGDocumentWriteToData )(CGSVGDocumentRef document, CFDataRef data, CFDictionaryRef options);
20
+ static void (*SDCGContextDrawSVGDocument )(CGContextRef context, CGSVGDocumentRef document);
21
+ static CGSize (*SDCGSVGDocumentGetCanvasSize )(CGSVGDocumentRef document);
22
22
23
23
#if SD_UIKIT || SD_WATCH
24
-
25
- @interface UIImage (PrivateSVGSupport)
26
-
27
- - (instancetype )_initWithCGSVGDocument : (CGSVGDocumentRef)document ;
28
- - (instancetype )_initWithCGSVGDocument : (CGSVGDocumentRef)document scale : (double )scale orientation : (UIImageOrientation)orientation ;
29
- + (instancetype )_imageWithCGSVGDocument : (CGSVGDocumentRef)document ;
30
- + (instancetype )_imageWithCGSVGDocument : (CGSVGDocumentRef)document scale : (double )scale orientation : (UIImageOrientation)orientation ;
31
- - (CGSVGDocumentRef)_CGSVGDocument ;
32
-
33
- @end
34
-
24
+ static SEL SDImageWithCGSVGDocumentSEL = NULL ;
25
+ static SEL SDCGSVGDocumentSEL = NULL ;
35
26
#endif
36
-
37
27
#if SD_MAC
38
-
39
- #define NSSVGImageRepClass @" _NSSVGImageRep"
40
- #define NSSVGImageRepDocumentIvar " _document"
41
-
42
- @protocol NSSVGImageRepProtocol <NSObject >
43
-
44
- - (instancetype )initWithSVGDocument : (CGSVGDocumentRef)document ;
45
- - (instancetype )initWithData : (NSData *)data ;
46
-
47
- @end
48
-
28
+ static Class SDNSSVGImageRepClass = NULL ;
49
29
#endif
50
30
31
+ static inline NSString *SDBase64DecodedString (NSString *base64String) {
32
+ NSData *data = [[NSData alloc ] initWithBase64EncodedString: base64String options: NSDataBase64DecodingIgnoreUnknownCharacters ];
33
+ if (!data) {
34
+ return nil ;
35
+ }
36
+ return [[NSString alloc ] initWithData: data encoding: NSUTF8StringEncoding];
37
+ }
38
+
51
39
@implementation SDImageSVGCoder
52
40
53
41
+ (SDImageSVGCoder *)sharedCoder {
@@ -60,12 +48,19 @@ + (SDImageSVGCoder *)sharedCoder {
60
48
}
61
49
62
50
+ (void )initialize {
63
- CGSVGDocumentRetain = dlsym (RTLD_DEFAULT, " CGSVGDocumentRetain" );
64
- CGSVGDocumentRelease = dlsym (RTLD_DEFAULT, " CGSVGDocumentRelease" );
65
- CGSVGDocumentCreateFromData = dlsym (RTLD_DEFAULT, " CGSVGDocumentCreateFromData" );
66
- CGSVGDocumentWriteToData = dlsym (RTLD_DEFAULT, " CGSVGDocumentWriteToData" );
67
- CGContextDrawSVGDocument = dlsym (RTLD_DEFAULT, " CGContextDrawSVGDocument" );
68
- CGSVGDocumentGetCanvasSize = dlsym (RTLD_DEFAULT, " CGSVGDocumentGetCanvasSize" );
51
+ SDCGSVGDocumentRetain = dlsym (RTLD_DEFAULT, SDBase64DecodedString (@" Q0dTVkdEb2N1bWVudFJldGFpbg==" ).UTF8String );
52
+ SDCGSVGDocumentRelease = dlsym (RTLD_DEFAULT, SDBase64DecodedString (@" Q0dTVkdEb2N1bWVudFJlbGVhc2U=" ).UTF8String );
53
+ SDCGSVGDocumentCreateFromData = dlsym (RTLD_DEFAULT, SDBase64DecodedString (@" Q0dTVkdEb2N1bWVudENyZWF0ZUZyb21EYXRh" ).UTF8String );
54
+ SDCGSVGDocumentWriteToData = dlsym (RTLD_DEFAULT, SDBase64DecodedString (@" Q0dTVkdEb2N1bWVudFdyaXRlVG9EYXRh" ).UTF8String );
55
+ SDCGContextDrawSVGDocument = dlsym (RTLD_DEFAULT, SDBase64DecodedString (@" Q0dDb250ZXh0RHJhd1NWR0RvY3VtZW50" ).UTF8String );
56
+ SDCGSVGDocumentGetCanvasSize = dlsym (RTLD_DEFAULT, SDBase64DecodedString (@" Q0dTVkdEb2N1bWVudEdldENhbnZhc1NpemU=" ).UTF8String );
57
+ #if SD_UIKIT
58
+ SDImageWithCGSVGDocumentSEL = NSSelectorFromString (SDBase64DecodedString (@" X2ltYWdlV2l0aENHU1ZHRG9jdW1lbnQ6" ));
59
+ SDCGSVGDocumentSEL = NSSelectorFromString (SDBase64DecodedString (@" X0NHU1ZHRG9jdW1lbnQ=" ));
60
+ #endif
61
+ #if SD_MAC
62
+ SDNSSVGImageRepClass = NSClassFromString (SDBase64DecodedString (@" X05TU1ZHSW1hZ2VSZXA=" ));
63
+ #endif
69
64
}
70
65
71
66
#pragma mark - Decode
@@ -129,18 +124,19 @@ - (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format o
129
124
#if SD_MAC
130
125
NSRect imageRect = NSMakeRect (0 , 0 , image.size .width , image.size .height );
131
126
NSImageRep *imageRep = [image bestRepresentationForRect: imageRect context: nil hints: nil ];
132
- if ([imageRep isKindOfClass: NSClassFromString (NSSVGImageRepClass) ]) {
133
- Ivar ivar = class_getInstanceVariable (imageRep.class , NSSVGImageRepDocumentIvar );
127
+ if ([imageRep isKindOfClass: SDNSSVGImageRepClass ]) {
128
+ Ivar ivar = class_getInstanceVariable (imageRep.class , SDBase64DecodedString ( @" X2RvY3VtZW50 " ). UTF8String );
134
129
document = (__bridge CGSVGDocumentRef)(object_getIvar (imageRep, ivar));
135
130
}
136
131
#else
137
- document = [image _CGSVGDocument ];
132
+ CGSVGDocumentRef (*method)(id ,SEL ) = (CGSVGDocumentRef (*)(id ,SEL ))[image methodForSelector: SDCGSVGDocumentSEL];
133
+ document = method (image, SDCGSVGDocumentSEL);
138
134
#endif
139
135
if (!document) {
140
136
return nil ;
141
137
}
142
138
143
- CGSVGDocumentWriteToData (document, (__bridge CFDataRef)data, NULL );
139
+ SDCGSVGDocumentWriteToData (document, (__bridge CFDataRef)data, NULL );
144
140
145
141
return [data copy ];
146
142
}
@@ -151,20 +147,20 @@ - (UIImage *)createVectorSVGWithData:(nonnull NSData *)data {
151
147
UIImage *image;
152
148
153
149
#if SD_MAC
154
- Class imageRepClass = NSClassFromString (NSSVGImageRepClass) ;
150
+ Class imageRepClass = SDNSSVGImageRepClass ;
155
151
NSImageRep *imageRep = [[imageRepClass alloc ] initWithData: data];
156
152
if (!imageRep) {
157
153
return nil ;
158
154
}
159
155
image = [[NSImage alloc ] initWithSize: imageRep.size];
160
156
[image addRepresentation: imageRep];
161
157
#else
162
- CGSVGDocumentRef document = CGSVGDocumentCreateFromData ((__bridge CFDataRef)data, NULL );
158
+ CGSVGDocumentRef document = SDCGSVGDocumentCreateFromData ((__bridge CFDataRef)data, NULL );
163
159
if (!document) {
164
160
return nil ;
165
161
}
166
- image = [UIImage _imageWithCGSVGDocument: document];
167
- CGSVGDocumentRelease (document);
162
+ image = [UIImage performSelector: SDImageWithCGSVGDocumentSEL withObject: (__bridge id )( document) ];
163
+ SDCGSVGDocumentRelease (document);
168
164
#endif
169
165
return image;
170
166
}
@@ -174,12 +170,12 @@ - (UIImage *)createBitmapSVGWithData:(nonnull NSData *)data targetSize:(CGSize)t
174
170
NSParameterAssert (data);
175
171
UIImage *image;
176
172
177
- CGSVGDocumentRef document = CGSVGDocumentCreateFromData ((__bridge CFDataRef)data, NULL );
173
+ CGSVGDocumentRef document = SDCGSVGDocumentCreateFromData ((__bridge CFDataRef)data, NULL );
178
174
if (!document) {
179
175
return nil ;
180
176
}
181
177
182
- CGSize size = CGSVGDocumentGetCanvasSize (document);
178
+ CGSize size = SDCGSVGDocumentGetCanvasSize (document);
183
179
if (CGSizeEqualToSize (targetSize, CGSizeZero)) {
184
180
targetSize = size;
185
181
}
@@ -205,12 +201,12 @@ - (UIImage *)createBitmapSVGWithData:(nonnull NSData *)data targetSize:(CGSize)t
205
201
CGContextConcatCTM (context, translationTransform);
206
202
CGContextConcatCTM (context, scaleTransform);
207
203
208
- CGContextDrawSVGDocument (context, document);
204
+ SDCGContextDrawSVGDocument (context, document);
209
205
210
206
image = SDGraphicsGetImageFromCurrentImageContext ();
211
207
SDGraphicsEndImageContext ();
212
208
213
- CGSVGDocumentRelease (document);
209
+ SDCGSVGDocumentRelease (document);
214
210
215
211
return image;
216
212
}
@@ -223,14 +219,14 @@ + (BOOL)supportsVectorSVGImage {
223
219
dispatch_once (&onceToken, ^{
224
220
#if SD_MAC
225
221
// macOS 10.15+ supports SVG built-in rendering, use selector to check is more accurate
226
- if (NSClassFromString (NSSVGImageRepClass) ) {
222
+ if (SDNSSVGImageRepClass ) {
227
223
supports = YES ;
228
224
} else {
229
225
supports = NO ;
230
226
}
231
227
#else
232
228
// iOS 13+ supports SVG built-in rendering, use selector to check is more accurate
233
- if ([UIImage respondsToSelector: @selector ( _imageWithCGSVGDocument: ) ]) {
229
+ if ([UIImage respondsToSelector: SDImageWithCGSVGDocumentSEL ]) {
234
230
supports = YES ;
235
231
} else {
236
232
supports = NO ;
0 commit comments