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