Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 050df84672 | |||
| ac61d3d6d6 | |||
| fdde1fd5f6 | |||
| fe179076cc | |||
| 01dd0d25d2 | |||
| 799593d7d8 | |||
| 0c7cfd776c | |||
| 757c4317d3 | |||
| 1727505968 | |||
| 775c28e91a | |||
| ec539a12b3 | |||
| 43210c018e | |||
| 3773e10f44 | |||
| 51fb9cc871 | |||
| be08ada5da | |||
| a3a6ee5a05 | |||
| cccfc0db68 | |||
| 19db898bdd | |||
| 8abbdf390a | |||
| 6e98e2cfed | |||
| 2c536a8962 | |||
| 65a8c0a691 | |||
| 2942cc0a58 | |||
| ba7a05553e | |||
| c9a7788d98 | |||
| 774ff48074 | |||
| 2eb629cd21 | |||
| 137e34623f | |||
| 39b0b5bbb4 | |||
| 820fca2679 | |||
| 2e5819183d | |||
| eff56d3c60 | |||
| 7a4fd35a64 | |||
| 964dc3005d | |||
| 1a8d44ec95 | |||
| 717198457b | |||
| e2991ab8b0 | |||
| dda3e5ed8c |
@@ -0,0 +1 @@
|
||||
.DS_Store
|
||||
@@ -7,6 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
590EB7A427F637EF0047CECF /* IJSVGTransformLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 590EB7A227F637EF0047CECF /* IJSVGTransformLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
590EB7A527F637EF0047CECF /* IJSVGTransformLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 590EB7A327F637EF0047CECF /* IJSVGTransformLayer.m */; };
|
||||
5919E65723F47FF60051873A /* IJSVGUnitRect.h in Headers */ = {isa = PBXBuildFile; fileRef = 5919E65523F47FF60051873A /* IJSVGUnitRect.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
5919E65823F47FF60051873A /* IJSVGUnitRect.m in Sources */ = {isa = PBXBuildFile; fileRef = 5919E65623F47FF60051873A /* IJSVGUnitRect.m */; };
|
||||
5919E65B23F480330051873A /* IJSVGUnitPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5919E65923F480330051873A /* IJSVGUnitPoint.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -18,6 +20,8 @@
|
||||
594CF55F238FF462009B251B /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF55E238FF462009B251B /* AppKit.framework */; };
|
||||
594CF561238FF46C009B251B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF560238FF46C009B251B /* Foundation.framework */; };
|
||||
594CF563238FF473009B251B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF562238FF473009B251B /* QuartzCore.framework */; };
|
||||
5978C46A280A241200D25296 /* IJSVGRootLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5978C468280A241200D25296 /* IJSVGRootLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
5978C46B280A241200D25296 /* IJSVGRootLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5978C469280A241200D25296 /* IJSVGRootLayer.m */; };
|
||||
599EB4D3238FF570004CB6BC /* libobjc.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 599EB4D2238FF535004CB6BC /* libobjc.tbd */; };
|
||||
59A24EBC23F480EA0090C374 /* IJSVGUnitSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 59A24EBA23F480EA0090C374 /* IJSVGUnitSize.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59A24EBD23F480EA0090C374 /* IJSVGUnitSize.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A24EBB23F480EA0090C374 /* IJSVGUnitSize.m */; };
|
||||
@@ -132,9 +136,17 @@
|
||||
59EB764623905F7300F5AE63 /* IJSVGRendering.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75D523905F7300F5AE63 /* IJSVGRendering.m */; };
|
||||
59F36508262F1ABB00BCE3FD /* IJSVGColorType.h in Headers */ = {isa = PBXBuildFile; fileRef = 59F36506262F1ABB00BCE3FD /* IJSVGColorType.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59F36509262F1ABB00BCE3FD /* IJSVGColorType.m in Sources */ = {isa = PBXBuildFile; fileRef = 59F36507262F1ABB00BCE3FD /* IJSVGColorType.m */; };
|
||||
59F9EAF82808BB5F00188ACB /* IJSVGViewBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 59F9EAF62808BB5F00188ACB /* IJSVGViewBox.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59F9EAF92808BB5F00188ACB /* IJSVGViewBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 59F9EAF72808BB5F00188ACB /* IJSVGViewBox.m */; };
|
||||
59FCC09427F2394D00BB924E /* IJSVGRootNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 59FCC09227F2394D00BB924E /* IJSVGRootNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59FCC09527F2394D00BB924E /* IJSVGRootNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 59FCC09327F2394D00BB924E /* IJSVGRootNode.m */; };
|
||||
59FDBF0027F3454800AF7038 /* IJSVGColorNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 59FDBEFE27F3454800AF7038 /* IJSVGColorNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59FDBF0127F3454800AF7038 /* IJSVGColorNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 59FDBEFF27F3454800AF7038 /* IJSVGColorNode.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
590EB7A227F637EF0047CECF /* IJSVGTransformLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGTransformLayer.h; sourceTree = "<group>"; };
|
||||
590EB7A327F637EF0047CECF /* IJSVGTransformLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGTransformLayer.m; sourceTree = "<group>"; };
|
||||
5919E65523F47FF60051873A /* IJSVGUnitRect.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGUnitRect.h; sourceTree = "<group>"; };
|
||||
5919E65623F47FF60051873A /* IJSVGUnitRect.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGUnitRect.m; sourceTree = "<group>"; };
|
||||
5919E65923F480330051873A /* IJSVGUnitPoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGUnitPoint.h; sourceTree = "<group>"; };
|
||||
@@ -148,6 +160,8 @@
|
||||
594CF55E238FF462009B251B /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
594CF560238FF46C009B251B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
594CF562238FF473009B251B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
5978C468280A241200D25296 /* IJSVGRootLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGRootLayer.h; sourceTree = "<group>"; };
|
||||
5978C469280A241200D25296 /* IJSVGRootLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGRootLayer.m; sourceTree = "<group>"; };
|
||||
599EB4D2238FF535004CB6BC /* libobjc.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libobjc.tbd; path = usr/lib/libobjc.tbd; sourceTree = SDKROOT; };
|
||||
59A24EBA23F480EA0090C374 /* IJSVGUnitSize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGUnitSize.h; sourceTree = "<group>"; };
|
||||
59A24EBB23F480EA0090C374 /* IJSVGUnitSize.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGUnitSize.m; sourceTree = "<group>"; };
|
||||
@@ -262,6 +276,12 @@
|
||||
59EB75D523905F7300F5AE63 /* IJSVGRendering.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGRendering.m; sourceTree = "<group>"; };
|
||||
59F36506262F1ABB00BCE3FD /* IJSVGColorType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGColorType.h; sourceTree = "<group>"; };
|
||||
59F36507262F1ABB00BCE3FD /* IJSVGColorType.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGColorType.m; sourceTree = "<group>"; };
|
||||
59F9EAF62808BB5F00188ACB /* IJSVGViewBox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGViewBox.h; sourceTree = "<group>"; };
|
||||
59F9EAF72808BB5F00188ACB /* IJSVGViewBox.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGViewBox.m; sourceTree = "<group>"; };
|
||||
59FCC09227F2394D00BB924E /* IJSVGRootNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGRootNode.h; sourceTree = "<group>"; };
|
||||
59FCC09327F2394D00BB924E /* IJSVGRootNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGRootNode.m; sourceTree = "<group>"; };
|
||||
59FDBEFE27F3454800AF7038 /* IJSVGColorNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGColorNode.h; sourceTree = "<group>"; };
|
||||
59FDBEFF27F3454800AF7038 /* IJSVGColorNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGColorNode.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -355,6 +375,10 @@
|
||||
59EB757A23905F6C00F5AE63 /* IJSVGShapeLayer.m */,
|
||||
59EB75A423905F6E00F5AE63 /* IJSVGStrokeLayer.h */,
|
||||
59EB757423905F6C00F5AE63 /* IJSVGStrokeLayer.m */,
|
||||
590EB7A227F637EF0047CECF /* IJSVGTransformLayer.h */,
|
||||
590EB7A327F637EF0047CECF /* IJSVGTransformLayer.m */,
|
||||
5978C468280A241200D25296 /* IJSVGRootLayer.h */,
|
||||
5978C469280A241200D25296 /* IJSVGRootLayer.m */,
|
||||
);
|
||||
path = Layers;
|
||||
sourceTree = "<group>";
|
||||
@@ -395,6 +419,10 @@
|
||||
59EB75AA23905F6F00F5AE63 /* IJSVGPattern.m */,
|
||||
59EB756B23905F6B00F5AE63 /* IJSVGText.h */,
|
||||
59EB75C023905F7100F5AE63 /* IJSVGText.m */,
|
||||
59FCC09227F2394D00BB924E /* IJSVGRootNode.h */,
|
||||
59FCC09327F2394D00BB924E /* IJSVGRootNode.m */,
|
||||
59FDBEFE27F3454800AF7038 /* IJSVGColorNode.h */,
|
||||
59FDBEFF27F3454800AF7038 /* IJSVGColorNode.m */,
|
||||
);
|
||||
path = Nodes;
|
||||
sourceTree = "<group>";
|
||||
@@ -422,6 +450,8 @@
|
||||
59A24EBB23F480EA0090C374 /* IJSVGUnitSize.m */,
|
||||
591A3E4B25CC91F800AD45B7 /* IJSVGParsing.h */,
|
||||
591A3E4C25CC91F800AD45B7 /* IJSVGParsing.m */,
|
||||
59F9EAF62808BB5F00188ACB /* IJSVGViewBox.h */,
|
||||
59F9EAF72808BB5F00188ACB /* IJSVGViewBox.m */,
|
||||
);
|
||||
path = Utils;
|
||||
sourceTree = "<group>";
|
||||
@@ -597,8 +627,13 @@
|
||||
59E7CFAF23B148600077D599 /* IJSVGCommandParser.h in Headers */,
|
||||
59EB762823905F7300F5AE63 /* IJSVGCommandClose.h in Headers */,
|
||||
59EB75E423905F7300F5AE63 /* IJSVGGradientUnitLength.h in Headers */,
|
||||
59FCC09427F2394D00BB924E /* IJSVGRootNode.h in Headers */,
|
||||
594A10DA248D7C90001A3181 /* NSImage+IJSVGAdditions.h in Headers */,
|
||||
59EB762D23905F7300F5AE63 /* IJSVGLayerTree.h in Headers */,
|
||||
59FDBF0027F3454800AF7038 /* IJSVGColorNode.h in Headers */,
|
||||
590EB7A427F637EF0047CECF /* IJSVGTransformLayer.h in Headers */,
|
||||
5978C46A280A241200D25296 /* IJSVGRootLayer.h in Headers */,
|
||||
59F9EAF82808BB5F00188ACB /* IJSVGViewBox.h in Headers */,
|
||||
59EB760B23905F7300F5AE63 /* IJSVGStyleSheetSelector.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -696,6 +731,7 @@
|
||||
59EB760723905F7300F5AE63 /* IJSVGNode.m in Sources */,
|
||||
5919E65C23F480330051873A /* IJSVGUnitPoint.m in Sources */,
|
||||
59EB75E923905F7300F5AE63 /* IJSVGStringAdditions.m in Sources */,
|
||||
59FDBF0127F3454800AF7038 /* IJSVGColorNode.m in Sources */,
|
||||
59EB761723905F7300F5AE63 /* IJSVGRadialGradient.m in Sources */,
|
||||
59EB75E223905F7300F5AE63 /* IJSVGColorList.m in Sources */,
|
||||
59EB75ED23905F7300F5AE63 /* IJSVGFontConverter.m in Sources */,
|
||||
@@ -707,6 +743,7 @@
|
||||
59EB75F323905F7300F5AE63 /* IJSVGGroupLayer.m in Sources */,
|
||||
591A3E4E25CC91F800AD45B7 /* IJSVGParsing.m in Sources */,
|
||||
5919E65823F47FF60051873A /* IJSVGUnitRect.m in Sources */,
|
||||
5978C46B280A241200D25296 /* IJSVGRootLayer.m in Sources */,
|
||||
59EB762523905F7300F5AE63 /* IJSVGTransform.m in Sources */,
|
||||
59EB760023905F7300F5AE63 /* IJSVGGradientLayer.m in Sources */,
|
||||
59EB762B23905F7300F5AE63 /* IJSVGUnitLength.m in Sources */,
|
||||
@@ -718,14 +755,17 @@
|
||||
59EB762423905F7300F5AE63 /* IJSVGTransaction.m in Sources */,
|
||||
59EB75DA23905F7300F5AE63 /* IJSVGDef.m in Sources */,
|
||||
59EB763723905F7300F5AE63 /* IJSVGCommandClose.m in Sources */,
|
||||
59F9EAF92808BB5F00188ACB /* IJSVGViewBox.m in Sources */,
|
||||
59EB764323905F7300F5AE63 /* IJSVGGradient.m in Sources */,
|
||||
59EB762A23905F7300F5AE63 /* IJSVGGradientUnitLength.m in Sources */,
|
||||
59EB764223905F7300F5AE63 /* IJSVGStyleSheet.m in Sources */,
|
||||
59EB764023905F7300F5AE63 /* IJSVGExporterPathInstruction.m in Sources */,
|
||||
59EB75FE23905F7300F5AE63 /* IJSVGRenderingStyle.m in Sources */,
|
||||
59EB75F223905F7300F5AE63 /* IJSVGStyleSheetSelectorRaw.m in Sources */,
|
||||
590EB7A527F637EF0047CECF /* IJSVGTransformLayer.m in Sources */,
|
||||
59EB75EE23905F7300F5AE63 /* IJSVGImageRep.m in Sources */,
|
||||
59EB762223905F7300F5AE63 /* IJSVGMath.m in Sources */,
|
||||
59FCC09527F2394D00BB924E /* IJSVGRootNode.m in Sources */,
|
||||
59EB763D23905F7300F5AE63 /* IJSVGGroup.m in Sources */,
|
||||
59EB761F23905F7300F5AE63 /* IJSVGCommandLineTo.m in Sources */,
|
||||
59EB75F123905F7300F5AE63 /* IJSVGUtils.m in Sources */,
|
||||
|
||||
BIN
Binary file not shown.
@@ -181,6 +181,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
+ (NSString*)colorStringFromColor:(NSColor*)color;
|
||||
+ (NSColor*)colorFromHEXInteger:(NSInteger)hex;
|
||||
+ (NSColor*)computeColor:(id)colour;
|
||||
+ (BOOL)isNoneOrTransparent:(NSString*)string;
|
||||
+ (NSColor*)colorFromString:(NSString*)string;
|
||||
+ (NSColor*)colorFromHEXString:(NSString*)string;
|
||||
+ (NSColor*)colorFromHEXString:(NSString*)string
|
||||
|
||||
@@ -244,6 +244,12 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
alpha:a]];
|
||||
}
|
||||
|
||||
+ (BOOL)isNoneOrTransparent:(NSString*)string
|
||||
{
|
||||
const char* str = string.lowercaseString.UTF8String;
|
||||
return strcmp(str, "none") == 0 || strcmp(str, "transparent") == 0;
|
||||
}
|
||||
|
||||
+ (NSColor*)colorFromString:(NSString*)string
|
||||
{
|
||||
// swap over to C for performance
|
||||
@@ -251,14 +257,15 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
return nil;
|
||||
}
|
||||
|
||||
char* str = (char*)string.UTF8String;
|
||||
if(strlen(str) == 0) {
|
||||
const char* oString = string.UTF8String;
|
||||
if(strlen(oString) == 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
IJSVGTrimCharBuffer(str);
|
||||
char* str = IJSVGTimmedCharBufferCreate(oString);
|
||||
if (IJSVGCharBufferIsHEX(str) == YES) {
|
||||
return [self.class colorFromHEXString:string];
|
||||
(void)free(str), str = NULL;
|
||||
return [self.class colorFromHEXString:string];
|
||||
}
|
||||
|
||||
// is it RGB?
|
||||
@@ -268,6 +275,9 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
methods = IJSVGParsingMethodParseString(str, &count);
|
||||
IJSVGParsingStringMethod* method = methods[0];
|
||||
|
||||
// memory clean for the string
|
||||
(void)free(str), str = NULL;
|
||||
|
||||
// nothing to return, just mem clean and get out of here
|
||||
if(count == 0 || methods == NULL) {
|
||||
if(methods != NULL) {
|
||||
@@ -313,6 +323,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
color = [self computeColorSpace:color];
|
||||
|
||||
// memory clean!
|
||||
(void)free(str), str = NULL;
|
||||
(void)free(hsb), hsb = NULL;
|
||||
(void)free(params), params = NULL;
|
||||
return color;
|
||||
@@ -321,10 +332,12 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
// is simply a clear color, dont fill
|
||||
if (strcmp(str, "none") == 0 ||
|
||||
strcmp(str, "transparent") == 0) {
|
||||
return [self computeColorSpace:NSColor.clearColor];
|
||||
(void)free(str), str = NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
// could return nil
|
||||
(void)free(str), str = NULL;
|
||||
return [self.class colorFromPredefinedColorName:string];
|
||||
}
|
||||
|
||||
|
||||
@@ -17,12 +17,11 @@ typedef NS_ENUM(NSInteger, IJSVGCommandType) {
|
||||
kIJSVGCommandTypeRelative
|
||||
};
|
||||
|
||||
@interface IJSVGCommand : NSObject {
|
||||
@interface IJSVGCommand : NSObject <NSCopying> {
|
||||
@private
|
||||
NSInteger _currentIndex;
|
||||
}
|
||||
|
||||
@property (nonatomic, copy) NSString* commandString;
|
||||
@property (nonatomic, assign) char command;
|
||||
@property (nonatomic, assign) CGFloat* parameters;
|
||||
@property (nonatomic, assign) NSInteger parameterCount;
|
||||
@@ -41,17 +40,30 @@ typedef NS_ENUM(NSInteger, IJSVGCommandType) {
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path;
|
||||
path:(CGMutablePathRef)path;
|
||||
+ (void)parseParams:(CGFloat*)params
|
||||
paramCount:(NSInteger)paramCount
|
||||
intoArray:(NSMutableArray<IJSVGCommand*>*)commands
|
||||
parentCommand:(IJSVGCommand*)parentCommand;
|
||||
|
||||
+ (NSArray<IJSVGCommand*>*)commandsForDataCharacters:(const char*)buffer;
|
||||
+ (NSArray<IJSVGCommand*>*)commandsForDataCharacters:(const char*)buffer
|
||||
dataStream:(IJSVGPathDataStream*)dataStream;
|
||||
+ (CGMutablePathRef)newPathForCommandsArray:(NSArray<IJSVGCommand*>*)commands;
|
||||
|
||||
+ (NSArray<IJSVGCommand*>*)convertCommands:(NSArray<IJSVGCommand*>*)commands
|
||||
toUnits:(IJSVGUnitType)unitType
|
||||
bounds:(CGRect)bounds;
|
||||
|
||||
- (id)initWithCommandStringBuffer:(const char*)str
|
||||
dataStream:(IJSVGPathDataStream*)dataStream;
|
||||
- (IJSVGCommand*)subcommandWithParameters:(CGFloat*)subParams
|
||||
paramCount:(NSInteger)paramCount
|
||||
previousCommand:(IJSVGCommand*)command;
|
||||
- (void)convertToUnits:(IJSVGUnitType)units
|
||||
boundingBox:(CGRect)boundingBox;
|
||||
- (IJSVGCommand*)commandByConvertingToUnits:(IJSVGUnitType)unitType
|
||||
boundingBox:(CGRect)boundingBox;
|
||||
|
||||
- (CGFloat)readFloat;
|
||||
- (NSPoint)readPoint;
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
}
|
||||
|
||||
@@ -92,9 +92,95 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (CGMutablePathRef)newPathForCommandsArray:(NSArray<IJSVGCommand*>*)commands
|
||||
{
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
IJSVGCommand* preCommand = nil;
|
||||
for(IJSVGCommand* command in commands) {
|
||||
for (IJSVGCommand* subCommand in command.subCommands) {
|
||||
[command.class runWithParams:subCommand.parameters
|
||||
paramCount:subCommand.parameterCount
|
||||
command:subCommand
|
||||
previousCommand:preCommand
|
||||
type:subCommand.type
|
||||
path:path];
|
||||
preCommand = subCommand;
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
+ (NSArray<IJSVGCommand*>*)commandsForDataCharacters:(const char*)buffer
|
||||
{
|
||||
IJSVGPathDataStream* stream = IJSVGPathDataStreamCreateDefault();
|
||||
NSArray<IJSVGCommand*>* commands = [self commandsForDataCharacters:buffer
|
||||
dataStream:stream];
|
||||
IJSVGPathDataStreamRelease(stream);
|
||||
return commands;
|
||||
}
|
||||
|
||||
+ (NSArray<IJSVGCommand*>*)commandsForDataCharacters:(const char*)buffer
|
||||
dataStream:(IJSVGPathDataStream*)dataStream
|
||||
{
|
||||
NSMutableArray<IJSVGCommand*>* commands = [[[NSMutableArray alloc] init] autorelease];
|
||||
NSUInteger len = strlen(buffer);
|
||||
NSUInteger lastIndex = len - 1;
|
||||
|
||||
// make sure we plus 1 for the null byte
|
||||
char* charBuffer = (char*)malloc(sizeof(char)*(len + 1));
|
||||
NSInteger start = 0;
|
||||
for (NSInteger i = 0; i < len; i++) {
|
||||
char nextChar = buffer[i + 1];
|
||||
BOOL atEnd = i == lastIndex;
|
||||
BOOL isStartCommand = IJSVGIsLegalCommandCharacter(nextChar);
|
||||
if (isStartCommand == YES || atEnd == YES) {
|
||||
|
||||
// copy memory from current buffer
|
||||
NSInteger index = ((i + 1) - start);
|
||||
memcpy(&charBuffer[0], &buffer[start], sizeof(char)*index);
|
||||
charBuffer[index] = '\0';
|
||||
|
||||
// create the command from the substring
|
||||
unsigned long length = index + 1;
|
||||
size_t mlength = sizeof(char)*length;
|
||||
char* commandString = (char*)malloc(mlength);
|
||||
memcpy(commandString, &charBuffer[0], mlength);
|
||||
|
||||
// reset start position
|
||||
start = (i + 1);
|
||||
|
||||
// previous command is actual subcommand
|
||||
Class commandClass = [IJSVGCommand commandClassForCommandChar:commandString[0]];
|
||||
IJSVGCommand* command = nil;
|
||||
command = (IJSVGCommand*)[[[commandClass alloc] initWithCommandStringBuffer:commandString
|
||||
dataStream:dataStream] autorelease];
|
||||
|
||||
[commands addObject:command];
|
||||
|
||||
// free the memory as at this point, we are done with it
|
||||
(void)free(commandString), commandString = NULL;
|
||||
}
|
||||
}
|
||||
(void)free(charBuffer), charBuffer = NULL;
|
||||
return commands;
|
||||
}
|
||||
|
||||
+ (NSArray<IJSVGCommand*>*)convertCommands:(NSArray<IJSVGCommand*>*)commands
|
||||
toUnits:(IJSVGUnitType)unitType
|
||||
bounds:(CGRect)bounds
|
||||
{
|
||||
NSMutableArray<IJSVGCommand*>* newCommands = nil;
|
||||
newCommands = [[[NSMutableArray alloc] initWithCapacity:commands.count] autorelease];
|
||||
for(IJSVGCommand* command in commands) {
|
||||
IJSVGCommand* nCommand = [command commandByConvertingToUnits:unitType
|
||||
boundingBox:bounds];
|
||||
[newCommands addObject:nCommand];
|
||||
}
|
||||
return newCommands;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_commandString release]), _commandString = nil;
|
||||
(void)([_subCommands release]), _subCommands = nil;
|
||||
if (_parameters) {
|
||||
(void)(free(_parameters)), _parameters = nil;
|
||||
@@ -114,7 +200,7 @@
|
||||
NSInteger paramCount = [self.class requiredParameterCount];
|
||||
IJSVGPathDataSequence* sequence = [self.class pathDataSequence];
|
||||
_parameters = IJSVGParsePathDataStreamSequence(str, strlen(str),
|
||||
dataStream, sequence, [self.class requiredParameterCount], &sets);
|
||||
dataStream, sequence, paramCount, &sets);
|
||||
|
||||
if (sets <= 1) {
|
||||
CGFloat* subParams = [self parametersFromIndexOffset:0];
|
||||
@@ -151,6 +237,37 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setSubCommands:(NSArray<IJSVGCommand*>*)subCommands
|
||||
{
|
||||
(void)[_subCommands release], _subCommands = nil;
|
||||
_subCommands = subCommands.retain;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
IJSVGCommand* command = [[self.class alloc] init];
|
||||
command.type = self.type;
|
||||
command.command = self.command;
|
||||
command.isSubCommand = self.isSubCommand;
|
||||
command.parameterCount = self.parameterCount;
|
||||
size_t memsize = sizeof(CGFloat)*self.parameterCount;
|
||||
command.parameters = (CGFloat*)malloc(memsize);
|
||||
memcpy(command.parameters, self.parameters, memsize);
|
||||
|
||||
|
||||
IJSVGCommand* lastCommand = nil;
|
||||
NSMutableArray<IJSVGCommand*>* subcommands = nil;
|
||||
subcommands = [[[NSMutableArray alloc] initWithCapacity:self.subCommands.count] autorelease];
|
||||
for(IJSVGCommand* subcommand in self.subCommands) {
|
||||
IJSVGCommand* subCopy = [[subcommand copy] autorelease];
|
||||
subCopy.previousCommand = lastCommand;
|
||||
subCopy.isSubCommand = lastCommand != nil;
|
||||
[subcommands addObject:subCopy];
|
||||
}
|
||||
command.subCommands = subcommands;
|
||||
return command;
|
||||
}
|
||||
|
||||
- (CGFloat*)parametersFromIndexOffset:(NSInteger)index
|
||||
{
|
||||
CGFloat* subParams = 0;
|
||||
@@ -202,6 +319,15 @@
|
||||
_currentIndex = 0;
|
||||
}
|
||||
|
||||
- (void)convertToUnits:(IJSVGUnitType)units
|
||||
boundingBox:(CGRect)boundingBox
|
||||
{
|
||||
for(IJSVGCommand* command in _subCommands) {
|
||||
[command convertToUnits:units
|
||||
boundingBox:boundingBox];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
NSMutableString* str = [[[NSMutableString alloc] init] autorelease];
|
||||
@@ -214,4 +340,13 @@
|
||||
return str;
|
||||
}
|
||||
|
||||
- (IJSVGCommand*)commandByConvertingToUnits:(IJSVGUnitType)unitType
|
||||
boundingBox:(CGRect)boundingBox
|
||||
{
|
||||
IJSVGCommand* copy = self.copy;
|
||||
[copy convertToUnits:unitType
|
||||
boundingBox:boundingBox];
|
||||
return [copy autorelease];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
[path close];
|
||||
CGPathCloseSubpath(path);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,16 +20,16 @@
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddCurveToPoint(path.path, NULL, params[0], params[1],
|
||||
CGPathAddCurveToPoint(path, NULL, params[0], params[1],
|
||||
params[2], params[3],
|
||||
params[4], params[5]);
|
||||
return;
|
||||
}
|
||||
CGPoint currentPoint = path.currentPoint;
|
||||
CGPathAddCurveToPoint(path.path, NULL,
|
||||
CGPoint currentPoint = CGPathGetCurrentPoint(path);
|
||||
CGPathAddCurveToPoint(path, NULL,
|
||||
currentPoint.x + params[0], currentPoint.y + params[1],
|
||||
currentPoint.x + params[2], currentPoint.y + params[3],
|
||||
currentPoint.x + params[4], currentPoint.y + params[5]);
|
||||
|
||||
@@ -40,11 +40,11 @@ static IJSVGPathDataSequence* _sequence;
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
CGPoint radii = CGPointZero;
|
||||
CGPoint arcEndPoint = CGPointZero;
|
||||
CGPoint pathCurrentPoint = path.currentPoint;
|
||||
CGPoint pathCurrentPoint = CGPathGetCurrentPoint(path);
|
||||
CGFloat xAxisRotation = 0.f;
|
||||
BOOL largeArcFlag = NO;
|
||||
BOOL sweepFlag = NO;
|
||||
@@ -73,7 +73,7 @@ static IJSVGPathDataSequence* _sequence;
|
||||
CGFloat y2 = arcEndPoint.y;
|
||||
|
||||
if (rx == 0.f || ry == 0.f) {
|
||||
CGPathAddLineToPoint(path.path, NULL, x2, y2);
|
||||
CGPathAddLineToPoint(path, NULL, x2, y2);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ static IJSVGPathDataSequence* _sequence;
|
||||
transform = CGAffineTransformRotate(transform, xAxisRotation);
|
||||
transform = CGAffineTransformScale(transform, rx, ry);
|
||||
|
||||
CGPathAddRelativeArc(path.path, &transform, 0.f, 0.f, 1.f,
|
||||
CGPathAddRelativeArc(path, &transform, 0.f, 0.f, 1.f,
|
||||
startAngle, angleDelta);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddLineToPoint(path.path, NULL, params[0], path.currentPoint.y);
|
||||
CGPathAddLineToPoint(path, NULL, params[0], CGPathGetCurrentPoint(path).y);
|
||||
return;
|
||||
}
|
||||
CGPoint currentPoint = path.currentPoint;
|
||||
CGPathAddLineToPoint(path.path, NULL, currentPoint.x + params[0],
|
||||
path.currentPoint.y);
|
||||
CGPoint currentPoint = CGPathGetCurrentPoint(path);
|
||||
CGPathAddLineToPoint(path, NULL, currentPoint.x + params[0],
|
||||
currentPoint.y);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,15 +20,26 @@
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddLineToPoint(path.path, NULL, params[0], params[1]);
|
||||
CGPathAddLineToPoint(path, NULL, params[0], params[1]);
|
||||
return;
|
||||
}
|
||||
CGPoint currentPoint = path.currentPoint;
|
||||
CGPathAddLineToPoint(path.path, NULL, currentPoint.x + params[0],
|
||||
CGPoint currentPoint = CGPathGetCurrentPoint(path);
|
||||
CGPathAddLineToPoint(path, NULL, currentPoint.x + params[0],
|
||||
currentPoint.y + params[1]);
|
||||
}
|
||||
|
||||
- (void)convertToUnits:(IJSVGUnitType)units
|
||||
boundingBox:(CGRect)boundingBox
|
||||
{
|
||||
if(units == IJSVGUnitObjectBoundingBox) {
|
||||
self.parameters[0] = [[IJSVGUnitLength unitWithPercentageFloat:self.parameters[0]] computeValue:boundingBox.size.width];
|
||||
self.parameters[1] = [[IJSVGUnitLength unitWithPercentageFloat:self.parameters[1]] computeValue:boundingBox.size.height];
|
||||
}
|
||||
[super convertToUnits:units
|
||||
boundingBox:boundingBox];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
// move to's allow more then one move to, but if there are more then one,
|
||||
// we need to run the line to instead...who knew!
|
||||
@@ -41,14 +41,25 @@
|
||||
// there is no current point. Asking for current point on an empty
|
||||
// path will result in an exception being thrown
|
||||
if (type == kIJSVGCommandTypeAbsolute || command == nil) {
|
||||
CGPathMoveToPoint(path.path, NULL,
|
||||
CGPathMoveToPoint(path, NULL,
|
||||
params[0], params[1]);
|
||||
return;
|
||||
}
|
||||
CGPoint currentPoint = path.currentPoint;
|
||||
CGPathMoveToPoint(path.path, NULL,
|
||||
CGPoint currentPoint = CGPathGetCurrentPoint(path);
|
||||
CGPathMoveToPoint(path, NULL,
|
||||
currentPoint.x + params[0],
|
||||
currentPoint.y + params[1]);
|
||||
}
|
||||
|
||||
- (void)convertToUnits:(IJSVGUnitType)units
|
||||
boundingBox:(CGRect)boundingBox
|
||||
{
|
||||
if(units == IJSVGUnitObjectBoundingBox) {
|
||||
self.parameters[0] = [[IJSVGUnitLength unitWithPercentageFloat:self.parameters[0]] computeValue:boundingBox.size.width];
|
||||
self.parameters[1] = [[IJSVGUnitLength unitWithPercentageFloat:self.parameters[1]] computeValue:boundingBox.size.height];
|
||||
}
|
||||
[super convertToUnits:units
|
||||
boundingBox:boundingBox];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,15 +21,15 @@
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddQuadCurveToPoint(path.path, NULL, params[0], params[1],
|
||||
CGPathAddQuadCurveToPoint(path, NULL, params[0], params[1],
|
||||
params[2], params[3]);
|
||||
return;
|
||||
}
|
||||
CGPoint currentPoint = path.currentPoint;
|
||||
CGPathAddQuadCurveToPoint(path.path, NULL,
|
||||
CGPoint currentPoint = CGPathGetCurrentPoint(path);
|
||||
CGPathAddQuadCurveToPoint(path, NULL,
|
||||
currentPoint.x + params[0], currentPoint.y + params[1],
|
||||
currentPoint.x + params[2], currentPoint.y + params[3]);
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
CGPoint currentPoint = path.currentPoint;
|
||||
CGPoint currentPoint = CGPathGetCurrentPoint(path);
|
||||
CGPoint firstControl = CGPointMake(currentPoint.x, currentPoint.y);
|
||||
if (command != nil) {
|
||||
if (command.class == [IJSVGCommandCurve class] || command.class == self.class) {
|
||||
@@ -52,11 +52,11 @@
|
||||
}
|
||||
}
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddCurveToPoint(path.path, NULL, firstControl.x, firstControl.y,
|
||||
CGPathAddCurveToPoint(path, NULL, firstControl.x, firstControl.y,
|
||||
params[0], params[1], params[2], params[3]);
|
||||
return;
|
||||
}
|
||||
CGPathAddCurveToPoint(path.path, NULL, firstControl.x, firstControl.y,
|
||||
CGPathAddCurveToPoint(path, NULL, firstControl.x, firstControl.y,
|
||||
currentPoint.x + params[0], currentPoint.y + params[1],
|
||||
currentPoint.x + params[2], currentPoint.y + params[3]);
|
||||
}
|
||||
|
||||
@@ -22,9 +22,10 @@
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
CGPoint currentPoint = path.currentPoint;
|
||||
CGPoint lastControlPoint = IJSVGPathGetLastQuadraticCommandPoint(path);
|
||||
CGPoint currentPoint = CGPathGetCurrentPoint(path);
|
||||
CGPoint commandPoint = CGPointMake(currentPoint.x, currentPoint.y);
|
||||
if (command != nil) {
|
||||
if (command.class == IJSVGCommandQuadraticCurve.class) {
|
||||
@@ -40,17 +41,17 @@
|
||||
}
|
||||
} else if (command.class == self.class) {
|
||||
// smooth quadratic curve
|
||||
commandPoint = CGPointMake(-1 * (path.lastControlPoint.x) + 2 * (currentPoint.x),
|
||||
-1 * (path.lastControlPoint.y) + 2 * currentPoint.y);
|
||||
commandPoint = CGPointMake(-1 * (lastControlPoint.x) + 2 * (currentPoint.x),
|
||||
-1 * (lastControlPoint.y) + 2 * currentPoint.y);
|
||||
}
|
||||
}
|
||||
path.lastControlPoint = commandPoint;
|
||||
// path.lastControlPoint = commandPoint;
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddQuadCurveToPoint(path.path, NULL, commandPoint.x, commandPoint.y,
|
||||
CGPathAddQuadCurveToPoint(path, NULL, commandPoint.x, commandPoint.y,
|
||||
params[0], params[1]);
|
||||
return;
|
||||
}
|
||||
CGPathAddQuadCurveToPoint(path.path, NULL, commandPoint.x, commandPoint.y,
|
||||
CGPathAddQuadCurveToPoint(path, NULL, commandPoint.x, commandPoint.y,
|
||||
currentPoint.x + params[0], currentPoint.y + params[1]);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
command:(IJSVGCommand*)currentCommand
|
||||
previousCommand:(IJSVGCommand*)command
|
||||
type:(IJSVGCommandType)type
|
||||
path:(IJSVGPath*)path
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddLineToPoint(path.path, NULL, path.currentPoint.x, params[0]);
|
||||
CGPathAddLineToPoint(path, NULL, CGPathGetCurrentPoint(path).x, params[0]);
|
||||
return;
|
||||
}
|
||||
CGPoint currentPoint = path.currentPoint;
|
||||
CGPathAddLineToPoint(path.path, NULL, currentPoint.x, currentPoint.y + params[0]);
|
||||
CGPoint currentPoint = CGPathGetCurrentPoint(path);
|
||||
CGPathAddLineToPoint(path, NULL, currentPoint.x, currentPoint.y + params[0]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGColorList.h>
|
||||
#import <IJSVG/IJSVGRootNode.h>
|
||||
#import <IJSVG/IJSVGExporter.h>
|
||||
#import <IJSVG/IJSVGGradientLayer.h>
|
||||
#import <IJSVG/IJSVGGroupLayer.h>
|
||||
#import <IJSVG/IJSVGRootLayer.h>
|
||||
#import <IJSVG/IJSVGImageLayer.h>
|
||||
#import <IJSVG/IJSVGLayerTree.h>
|
||||
#import <IJSVG/IJSVGParser.h>
|
||||
@@ -29,35 +31,25 @@ typedef NS_OPTIONS(NSInteger, IJSVGMatchPropertiesMask) {
|
||||
@protocol IJSVGDelegate <NSObject, IJSVGParserDelegate>
|
||||
|
||||
@optional
|
||||
- (BOOL)svg:(IJSVG*)svg
|
||||
shouldHandleForeignObject:(IJSVGForeignObject*)foreignObject;
|
||||
- (void)svg:(IJSVG*)svg
|
||||
handleForeignObject:(IJSVGForeignObject*)foreignObject
|
||||
document:(NSXMLDocument*)document;
|
||||
- (void)svg:(IJSVG*)svg
|
||||
foundSubSVG:(IJSVG*)subSVG
|
||||
withSVGString:(NSString*)subSVGString;
|
||||
foundSubSVG:(IJSVG*)subSVG
|
||||
withSVGString:(NSString*)subSVGString;
|
||||
|
||||
@end
|
||||
|
||||
@interface IJSVG : NSObject <NSPasteboardWriting, IJSVGParserDelegate> {
|
||||
|
||||
@private
|
||||
IJSVGParser* _group;
|
||||
IJSVGRootNode* _rootNode;
|
||||
CGFloat _scale;
|
||||
CGFloat _clipScale;
|
||||
id<IJSVGDelegate> _delegate;
|
||||
IJSVGLayer* _layerTree;
|
||||
IJSVGLayerTree* _layerTree;
|
||||
CGRect _viewBox;
|
||||
CGFloat _backingScaleFactor;
|
||||
CGFloat _lastProposedBackingScale;
|
||||
IJSVGRenderQuality _lastProposedRenderQuality;
|
||||
CGFloat _backingScale;
|
||||
NSMutableDictionary* _replacementColors;
|
||||
|
||||
struct {
|
||||
unsigned int shouldHandleForeignObject : 1;
|
||||
unsigned int handleForeignObject : 1;
|
||||
unsigned int shouldHandleSubSVG : 1;
|
||||
} _respondsTo;
|
||||
}
|
||||
@@ -76,6 +68,8 @@ typedef NS_OPTIONS(NSInteger, IJSVGMatchPropertiesMask) {
|
||||
@property (nonatomic, readonly) IJSVGUnitSize * intrinsicSize;
|
||||
@property (nonatomic, copy) NSString* title;
|
||||
@property (nonatomic, copy) NSString* desc;
|
||||
@property (nonatomic, retain) IJSVGLayerTree* layerTree;
|
||||
@property (nonatomic, retain) IJSVGRootLayer* rootLayer;
|
||||
|
||||
- (void)prepForDrawingInView:(NSView*)view;
|
||||
- (BOOL)isFont;
|
||||
@@ -83,16 +77,11 @@ typedef NS_OPTIONS(NSInteger, IJSVGMatchPropertiesMask) {
|
||||
- (NSRect)viewBox;
|
||||
- (NSArray<IJSVGPath*>*)glyphs;
|
||||
- (NSString*)identifier;
|
||||
- (IJSVGLayer*)layer;
|
||||
- (IJSVGLayer*)layerWithTree:(IJSVGLayerTree*)tree;
|
||||
- (NSArray<IJSVG*>*)subSVGs:(BOOL)recursive;
|
||||
- (NSString*)SVGStringWithOptions:(IJSVGExporterOptions)options;
|
||||
- (NSString*)SVGStringWithOptions:(IJSVGExporterOptions)options
|
||||
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions;
|
||||
|
||||
- (CGFloat)computeBackingScale:(CGFloat)scale;
|
||||
- (void)discardDOM;
|
||||
|
||||
+ (id)svgNamed:(NSString*)string;
|
||||
+ (id)svgNamed:(NSString*)string
|
||||
delegate:(id<IJSVGDelegate>)delegate;
|
||||
@@ -169,9 +158,6 @@ typedef NS_OPTIONS(NSInteger, IJSVGMatchPropertiesMask) {
|
||||
- (NSData*)PDFDataWithRect:(NSRect)rect
|
||||
error:(NSError**)error;
|
||||
|
||||
- (void)beginVectorDraw;
|
||||
- (void)endVectorDraw;
|
||||
|
||||
- (NSRect)computeOriginalDrawingFrameWithSize:(NSSize)aSize;
|
||||
- (void)setNeedsDisplay;
|
||||
|
||||
|
||||
@@ -23,10 +23,11 @@
|
||||
(void)([_renderingBackingScaleHelper release]), _renderingBackingScaleHelper = nil;
|
||||
(void)([_replacementColors release]), _replacementColors = nil;
|
||||
(void)([_renderingStyle release]), _renderingStyle = nil;
|
||||
(void)([_group release]), _group = nil;
|
||||
(void)([_rootNode release]), _rootNode = nil;
|
||||
(void)([_intrinsicSize release]), _intrinsicSize = nil;
|
||||
(void)([_title release]), _title = nil;
|
||||
(void)([_desc release]), _desc = nil;
|
||||
(void)([_rootLayer release]), _rootLayer = nil;
|
||||
|
||||
// kill any memory that has been around
|
||||
(void)([_layerTree release]), _layerTree = nil;
|
||||
@@ -107,10 +108,13 @@
|
||||
__block IJSVGImageLayer* imageLayer = nil;
|
||||
|
||||
// create the layers we require
|
||||
IJSVGImage* imageNode = [[[IJSVGImage alloc] init] autorelease];
|
||||
imageNode.image = image;
|
||||
|
||||
BOOL hasTransaction = IJSVGBeginTransaction();
|
||||
layer = [[[IJSVGGroupLayer alloc] init] autorelease];
|
||||
imageLayer =
|
||||
[[[IJSVGImageLayer alloc] initWithImage:image] autorelease];
|
||||
[[[IJSVGImageLayer alloc] initWithImage:imageNode] autorelease];
|
||||
[layer addSublayer:imageLayer];
|
||||
if (hasTransaction == YES) {
|
||||
IJSVGEndTransaction();
|
||||
@@ -127,7 +131,6 @@
|
||||
// this completely bypasses passing of files
|
||||
if ((self = [super init]) != nil) {
|
||||
// keep the layer tree
|
||||
_layerTree = [group retain];
|
||||
_viewBox = viewBox;
|
||||
|
||||
// any setups
|
||||
@@ -205,15 +208,15 @@
|
||||
[self _checkDelegate];
|
||||
|
||||
// create the group
|
||||
_group = [[IJSVGParser groupForFileURL:aURL
|
||||
error:&anError
|
||||
delegate:self] retain];
|
||||
|
||||
IJSVGParser* parser = [IJSVGParser groupForFileURL:aURL
|
||||
error:&anError
|
||||
delegate:self];
|
||||
_rootNode = parser.rootNode.retain;
|
||||
[self _setupBasicInfoFromGroup];
|
||||
[self _setupBasicsFromAnyInitializer];
|
||||
|
||||
// something went wrong...
|
||||
if (_group == nil) {
|
||||
if (_rootNode == nil) {
|
||||
if (error != NULL) {
|
||||
*error = anError;
|
||||
}
|
||||
@@ -266,15 +269,16 @@
|
||||
[self _checkDelegate];
|
||||
|
||||
// setup the parser
|
||||
_group = [[IJSVGParser alloc] initWithSVGString:string
|
||||
error:&anError
|
||||
delegate:self];
|
||||
IJSVGParser* parser = [[[IJSVGParser alloc] initWithSVGString:string
|
||||
error:&anError
|
||||
delegate:self] autorelease];
|
||||
_rootNode = parser.rootNode.retain;
|
||||
|
||||
[self _setupBasicInfoFromGroup];
|
||||
[self _setupBasicsFromAnyInitializer];
|
||||
|
||||
// something went wrong :(
|
||||
if (_group == nil) {
|
||||
if (_rootNode == nil) {
|
||||
if (error != NULL) {
|
||||
*error = anError;
|
||||
}
|
||||
@@ -294,20 +298,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)discardDOM
|
||||
{
|
||||
// if we discard, we can no longer create a tree, so lets create tree
|
||||
// upfront before we kill anything
|
||||
[self layer];
|
||||
|
||||
// now clear memory
|
||||
(void)([_group release]), _group = nil;
|
||||
}
|
||||
|
||||
- (void)_setupBasicInfoFromGroup
|
||||
{
|
||||
_viewBox = _group.viewBox;
|
||||
_intrinsicSize = _group.intrinsicSize.retain;
|
||||
_viewBox = [_rootNode.viewBox computeValue:CGSizeZero];
|
||||
_intrinsicSize = _rootNode.intrinsicSize.retain;
|
||||
}
|
||||
|
||||
- (void)_setupBasicsFromAnyInitializer
|
||||
@@ -317,7 +311,6 @@
|
||||
self.renderQuality = kIJSVGRenderQualityFullResolution;
|
||||
|
||||
// setup low level backing scale
|
||||
_lastProposedBackingScale = 0.f;
|
||||
self.renderingBackingScaleHelper = ^CGFloat {
|
||||
return NSScreen.mainScreen.backingScaleFactor;
|
||||
};
|
||||
@@ -325,37 +318,32 @@
|
||||
|
||||
- (void)setTitle:(NSString*)title
|
||||
{
|
||||
_group.title = title;
|
||||
_rootNode.title = title;
|
||||
}
|
||||
|
||||
- (NSString*)title
|
||||
{
|
||||
return _group.title;
|
||||
return _rootNode.title;
|
||||
}
|
||||
|
||||
- (void)setDesc:(NSString*)description
|
||||
{
|
||||
_group.desc = description;
|
||||
_rootNode.desc = description;
|
||||
}
|
||||
|
||||
- (NSString*)desc
|
||||
{
|
||||
return _group.desc;
|
||||
return _rootNode.desc;
|
||||
}
|
||||
|
||||
- (NSString*)identifier
|
||||
{
|
||||
return _group.identifier;
|
||||
return _rootNode.identifier;
|
||||
}
|
||||
|
||||
- (void)_checkDelegate
|
||||
{
|
||||
_respondsTo.shouldHandleForeignObject =
|
||||
[_delegate respondsToSelector:@selector(svg:shouldHandleForeignObject:)];
|
||||
_respondsTo.handleForeignObject = [_delegate
|
||||
respondsToSelector:@selector(svg:handleForeignObject:document:)];
|
||||
_respondsTo.shouldHandleSubSVG =
|
||||
[_delegate respondsToSelector:@selector(svg:foundSubSVG:withSVGString:)];
|
||||
_respondsTo.shouldHandleSubSVG = [_delegate respondsToSelector:@selector(svg:foundSubSVG:withSVGString:)];
|
||||
}
|
||||
|
||||
- (NSRect)viewBox
|
||||
@@ -365,22 +353,22 @@
|
||||
|
||||
- (IJSVGGroup*)rootNode
|
||||
{
|
||||
return _group;
|
||||
return _rootNode;
|
||||
}
|
||||
|
||||
- (BOOL)isFont
|
||||
{
|
||||
return [_group isFont];
|
||||
return [_rootNode isFont];
|
||||
}
|
||||
|
||||
- (NSArray<IJSVGPath*>*)glyphs
|
||||
{
|
||||
return [_group glyphs];
|
||||
return [_rootNode glyphs];
|
||||
}
|
||||
|
||||
- (NSArray<IJSVG*>*)subSVGs:(BOOL)recursive
|
||||
{
|
||||
return [_group subSVGs:recursive];
|
||||
return [_rootNode subSVGs:recursive];
|
||||
}
|
||||
|
||||
- (NSString*)SVGStringWithOptions:(IJSVGExporterOptions)options
|
||||
@@ -454,7 +442,7 @@
|
||||
[self _beginDraw:rect];
|
||||
|
||||
// make sure we setup the scale based on the backing scale factor
|
||||
CGFloat scale = [self backingScaleFactor:NULL];
|
||||
CGFloat scale = [self backingScaleFactor];
|
||||
|
||||
// create the context and colorspace
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
@@ -544,10 +532,10 @@
|
||||
CGContextTranslateCTM(context, 0, -box.size.height);
|
||||
|
||||
// make sure we set the masks to path bits n bobs
|
||||
[self _beginVectorDraw];
|
||||
// [self _beginVectorDraw];
|
||||
// draw the icon
|
||||
[self _drawInRect:(NSRect)box context:context error:error];
|
||||
[self _endVectorDraw];
|
||||
// [self _endVectorDraw];
|
||||
|
||||
CGContextEndPage(context);
|
||||
|
||||
@@ -558,39 +546,39 @@
|
||||
return data;
|
||||
}
|
||||
|
||||
- (void)endVectorDraw
|
||||
{
|
||||
[self _endVectorDraw];
|
||||
}
|
||||
//- (void)endVectorDraw
|
||||
//{
|
||||
// [self _endVectorDraw];
|
||||
//}
|
||||
//
|
||||
//- (void)beginVectorDraw
|
||||
//{
|
||||
// [self _beginVectorDraw];
|
||||
//}
|
||||
|
||||
- (void)beginVectorDraw
|
||||
{
|
||||
[self _beginVectorDraw];
|
||||
}
|
||||
|
||||
- (void)_beginVectorDraw
|
||||
{
|
||||
// turn on converts masks to PDF's
|
||||
// as PDF context and layer masks dont work
|
||||
void (^block)(CALayer* layer, BOOL isMask, BOOL* stop) =
|
||||
^void(CALayer* layer, BOOL isMask, BOOL* stop) {
|
||||
((IJSVGLayer*)layer).convertMasksToPaths = YES;
|
||||
};
|
||||
[IJSVGLayer recursivelyWalkLayer:self.layer
|
||||
withBlock:block];
|
||||
}
|
||||
|
||||
- (void)_endVectorDraw
|
||||
{
|
||||
// turn of convert masks to paths as not
|
||||
// needed for generic rendering
|
||||
void (^block)(CALayer* layer, BOOL isMask, BOOL* stop) =
|
||||
^void(CALayer* layer, BOOL isMask, BOOL* stop) {
|
||||
((IJSVGLayer*)layer).convertMasksToPaths = NO;
|
||||
};
|
||||
[IJSVGLayer recursivelyWalkLayer:self.layer
|
||||
withBlock:block];
|
||||
}
|
||||
//- (void)_beginVectorDraw
|
||||
//{
|
||||
// // turn on converts masks to PDF's
|
||||
// // as PDF context and layer masks dont work
|
||||
// void (^block)(CALayer* layer, BOOL isMask, BOOL* stop) =
|
||||
// ^void(CALayer* layer, BOOL isMask, BOOL* stop) {
|
||||
// ((IJSVGLayer*)layer).convertMasksToPaths = YES;
|
||||
// };
|
||||
// [IJSVGLayer recursivelyWalkLayer:self.layer
|
||||
// withBlock:block];
|
||||
//}
|
||||
//
|
||||
//- (void)_endVectorDraw
|
||||
//{
|
||||
// // turn of convert masks to paths as not
|
||||
// // needed for generic rendering
|
||||
// void (^block)(CALayer* layer, BOOL isMask, BOOL* stop) =
|
||||
// ^void(CALayer* layer, BOOL isMask, BOOL* stop) {
|
||||
// ((IJSVGLayer*)layer).convertMasksToPaths = NO;
|
||||
// };
|
||||
// [IJSVGLayer recursivelyWalkLayer:self.layer
|
||||
// withBlock:block];
|
||||
//}
|
||||
|
||||
- (void)prepForDrawingInView:(NSView*)view
|
||||
{
|
||||
@@ -601,7 +589,7 @@
|
||||
}
|
||||
|
||||
// construct the layer before drawing
|
||||
[self layer];
|
||||
[self rootLayer];
|
||||
|
||||
// set the scale
|
||||
__block NSView* weakView = view;
|
||||
@@ -647,12 +635,6 @@
|
||||
error:error];
|
||||
}
|
||||
|
||||
- (CGFloat)computeBackingScale:(CGFloat)actualScale
|
||||
{
|
||||
_backingScale = actualScale;
|
||||
return (CGFloat)(_scale + actualScale);
|
||||
}
|
||||
|
||||
- (NSRect)computeRectDrawingInRect:(NSRect)rect
|
||||
isValid:(BOOL*)valid
|
||||
{
|
||||
@@ -689,152 +671,120 @@
|
||||
[self _drawInRect:rect context:context error:nil];
|
||||
}
|
||||
|
||||
//- (BOOL)_drawInRect:(NSRect)rect
|
||||
// context:(CGContextRef)ref
|
||||
// error:(NSError**)error
|
||||
//{
|
||||
// // prep for draw...
|
||||
// CGContextSaveGState(ref);
|
||||
// @try {
|
||||
// [self _beginDraw:rect];
|
||||
//
|
||||
// // we also need to calculate the viewport so we can clip
|
||||
// // the drawing if needed
|
||||
// BOOL canDraw = NO;
|
||||
// NSRect viewPort = [self computeRectDrawingInRect:rect isValid:&canDraw];
|
||||
// // check the viewport
|
||||
// if (canDraw == NO) {
|
||||
// if (error != NULL) {
|
||||
// *error = [[[NSError alloc] initWithDomain:IJSVGErrorDomain
|
||||
// code:IJSVGErrorDrawing
|
||||
// userInfo:nil] autorelease];
|
||||
// }
|
||||
// } else {
|
||||
// // clip to mask
|
||||
// if (self.clipToViewport == YES) {
|
||||
// CGContextClipToRect(ref, viewPort);
|
||||
// }
|
||||
//
|
||||
// // add the origin back onto the viewport
|
||||
// viewPort.origin.x -= (_viewBox.origin.x) * _scale;
|
||||
// viewPort.origin.y -= (_viewBox.origin.y) * _scale;
|
||||
//
|
||||
// // transforms
|
||||
// CGContextTranslateCTM(ref, viewPort.origin.x, viewPort.origin.y);
|
||||
// CGContextScaleCTM(ref, _scale, _scale);
|
||||
//
|
||||
// // do we need to update the backing scales on the
|
||||
// // layers?
|
||||
// [self backingScaleFactor:nil];
|
||||
//
|
||||
// CGInterpolationQuality quality;
|
||||
// switch (self.renderQuality) {
|
||||
// case kIJSVGRenderQualityLow: {
|
||||
// quality = kCGInterpolationLow;
|
||||
// break;
|
||||
// }
|
||||
// case kIJSVGRenderQualityOptimized: {
|
||||
// quality = kCGInterpolationMedium;
|
||||
// break;
|
||||
// }
|
||||
// default: {
|
||||
// quality = kCGInterpolationHigh;
|
||||
// }
|
||||
// }
|
||||
// CGContextSetInterpolationQuality(ref, quality);
|
||||
// BOOL hasTransaction = IJSVGBeginTransaction();
|
||||
// [self.layer renderInContext:ref];
|
||||
// if (hasTransaction == YES) {
|
||||
// IJSVGEndTransaction();
|
||||
// }
|
||||
// }
|
||||
// } @catch (NSException* exception) {
|
||||
// // just catch and give back a drawing error to the caller
|
||||
// if (error != NULL) {
|
||||
// *error = [[[NSError alloc] initWithDomain:IJSVGErrorDomain
|
||||
// code:IJSVGErrorDrawing
|
||||
// userInfo:nil] autorelease];
|
||||
// }
|
||||
// }
|
||||
// CGContextRestoreGState(ref);
|
||||
// return (error == nil);
|
||||
//}
|
||||
|
||||
- (BOOL)_drawInRect:(NSRect)rect
|
||||
context:(CGContextRef)ref
|
||||
error:(NSError**)error
|
||||
{
|
||||
// prep for draw...
|
||||
BOOL transaction = IJSVGBeginTransaction();
|
||||
CGContextSaveGState(ref);
|
||||
@try {
|
||||
[self _beginDraw:rect];
|
||||
|
||||
// we also need to calculate the viewport so we can clip
|
||||
// the drawing if needed
|
||||
BOOL canDraw = NO;
|
||||
NSRect viewPort = [self computeRectDrawingInRect:rect isValid:&canDraw];
|
||||
// check the viewport
|
||||
if (canDraw == NO) {
|
||||
if (error != NULL) {
|
||||
*error = [[[NSError alloc] initWithDomain:IJSVGErrorDomain
|
||||
code:IJSVGErrorDrawing
|
||||
userInfo:nil] autorelease];
|
||||
}
|
||||
} else {
|
||||
// clip to mask
|
||||
if (self.clipToViewport == YES) {
|
||||
CGContextClipToRect(ref, viewPort);
|
||||
}
|
||||
|
||||
// add the origin back onto the viewport
|
||||
viewPort.origin.x -= (_viewBox.origin.x) * _scale;
|
||||
viewPort.origin.y -= (_viewBox.origin.y) * _scale;
|
||||
|
||||
// transforms
|
||||
CGContextTranslateCTM(ref, viewPort.origin.x, viewPort.origin.y);
|
||||
CGContextScaleCTM(ref, _scale, _scale);
|
||||
|
||||
// do we need to update the backing scales on the
|
||||
// layers?
|
||||
[self backingScaleFactor:nil];
|
||||
|
||||
CGInterpolationQuality quality;
|
||||
switch (self.renderQuality) {
|
||||
case kIJSVGRenderQualityLow: {
|
||||
quality = kCGInterpolationLow;
|
||||
break;
|
||||
}
|
||||
case kIJSVGRenderQualityOptimized: {
|
||||
quality = kCGInterpolationMedium;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
quality = kCGInterpolationHigh;
|
||||
}
|
||||
}
|
||||
CGContextSetInterpolationQuality(ref, quality);
|
||||
BOOL hasTransaction = IJSVGBeginTransaction();
|
||||
[self.layer renderInContext:ref];
|
||||
if (hasTransaction == YES) {
|
||||
IJSVGEndTransaction();
|
||||
}
|
||||
}
|
||||
} @catch (NSException* exception) {
|
||||
// just catch and give back a drawing error to the caller
|
||||
if (error != NULL) {
|
||||
*error = [[[NSError alloc] initWithDomain:IJSVGErrorDomain
|
||||
code:IJSVGErrorDrawing
|
||||
userInfo:nil] autorelease];
|
||||
}
|
||||
}
|
||||
// make sure we setup a transaction
|
||||
CGFloat backingScale = [self backingScaleFactor];
|
||||
[self.rootLayer renderInContext:ref
|
||||
viewPort:rect
|
||||
backingScale:backingScale
|
||||
quality:_renderQuality];
|
||||
CGContextRestoreGState(ref);
|
||||
return (error == nil);
|
||||
if(transaction) {
|
||||
IJSVGEndTransaction();
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (CGFloat)backingScaleFactor:(CGFloat* _Nullable)proposedBackingScale
|
||||
- (IJSVGLayerTree*)layerTree
|
||||
{
|
||||
if(_layerTree == nil) {
|
||||
_layerTree = [[IJSVGLayerTree alloc] init];
|
||||
}
|
||||
return _layerTree;
|
||||
}
|
||||
|
||||
- (IJSVGRootLayer*)rootLayer
|
||||
{
|
||||
if(_rootLayer == nil) {
|
||||
_rootLayer = [self.layerTree rootLayerForRootNode:_rootNode].retain;
|
||||
}
|
||||
return _rootLayer;
|
||||
}
|
||||
|
||||
- (CGFloat)backingScaleFactor
|
||||
{
|
||||
__block CGFloat scale = 1.f;
|
||||
scale = (self.renderingBackingScaleHelper)();
|
||||
if (scale < 1.f) {
|
||||
scale = 1.f;
|
||||
}
|
||||
_backingScaleFactor = scale;
|
||||
|
||||
// make sure we multiple the scale by the scale of the rendered clip
|
||||
// or it will be blurry for gradients and other bitmap drawing
|
||||
scale = (_scale * scale);
|
||||
|
||||
// dont do anything, nothing has changed, no point of iterating over
|
||||
// every layer for no reason!
|
||||
if (scale == _lastProposedBackingScale && _renderQuality == _lastProposedRenderQuality) {
|
||||
return _backingScaleFactor;
|
||||
}
|
||||
|
||||
IJSVGRenderQuality quality = self.renderQuality;
|
||||
_lastProposedBackingScale = scale;
|
||||
_lastProposedRenderQuality = quality;
|
||||
if (proposedBackingScale != nil && proposedBackingScale != NULL) {
|
||||
*proposedBackingScale = scale;
|
||||
}
|
||||
|
||||
// walk the tree
|
||||
void (^block)(CALayer* layer, BOOL isMask, BOOL* stop) =
|
||||
^void(CALayer* layer, BOOL isMask, BOOL* stop) {
|
||||
IJSVGLayer* propLayer = ((IJSVGLayer*)layer);
|
||||
propLayer.renderQuality = quality;
|
||||
if (propLayer.requiresBackingScaleHelp == YES) {
|
||||
propLayer.backingScaleFactor = scale;
|
||||
}
|
||||
};
|
||||
|
||||
// gogogo
|
||||
BOOL hasTransaction = IJSVGBeginTransaction();
|
||||
[IJSVGLayer recursivelyWalkLayer:self.layer withBlock:block];
|
||||
if (hasTransaction == YES) {
|
||||
IJSVGEndTransaction();
|
||||
}
|
||||
return _backingScaleFactor;
|
||||
}
|
||||
|
||||
- (IJSVGLayer*)layerWithTree:(IJSVGLayerTree*)tree
|
||||
{
|
||||
// clear memory
|
||||
BOOL hasTransaction = IJSVGBeginTransaction();
|
||||
if (_layerTree != nil) {
|
||||
(void)([_layerTree release]), _layerTree = nil;
|
||||
}
|
||||
|
||||
// force rebuild of the tree
|
||||
_layerTree = [[tree layerForNode:_group] retain];
|
||||
if (hasTransaction == YES) {
|
||||
IJSVGEndTransaction();
|
||||
}
|
||||
return _layerTree;
|
||||
}
|
||||
|
||||
- (IJSVGLayer*)layer
|
||||
{
|
||||
if (_layerTree != nil) {
|
||||
return _layerTree;
|
||||
}
|
||||
|
||||
// create the renderer and assign default values
|
||||
// from this SVG object
|
||||
IJSVGLayerTree* renderer = [[[IJSVGLayerTree alloc] init] autorelease];
|
||||
renderer.viewBox = self.viewBox;
|
||||
renderer.style = self.renderingStyle;
|
||||
|
||||
// return the rendered layer
|
||||
return [self layerWithTree:renderer];
|
||||
return _backingScale = scale;
|
||||
}
|
||||
|
||||
- (void)setRenderingStyle:(IJSVGRenderingStyle*)style
|
||||
@@ -867,12 +817,12 @@
|
||||
- (IJSVGColorList*)colorList
|
||||
{
|
||||
IJSVGColorList* sheet = [[[IJSVGColorList alloc] init] autorelease];
|
||||
void (^block)(CALayer* layer, BOOL isMask, BOOL* stop) =
|
||||
^void(CALayer* layer, BOOL isMask, BOOL* stop) {
|
||||
void (^block)(CALayer* layer, BOOL* stop) =
|
||||
^void(CALayer* layer, BOOL* stop) {
|
||||
|
||||
// dont do anything
|
||||
if(([layer isKindOfClass:IJSVGShapeLayer.class] && isMask == NO &&
|
||||
layer.isHidden == NO) == false) {
|
||||
if(([layer isKindOfClass:IJSVGShapeLayer.class] &&
|
||||
layer.isHidden == NO) == NO) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -928,7 +878,7 @@
|
||||
};
|
||||
|
||||
// gogogo!
|
||||
[IJSVGLayer recursivelyWalkLayer:self.layer
|
||||
[IJSVGLayer recursivelyWalkLayer:self.rootLayer
|
||||
withBlock:block];
|
||||
return sheet;
|
||||
}
|
||||
@@ -978,27 +928,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)svgParser:(IJSVGParser*)parser
|
||||
shouldHandleForeignObject:(IJSVGForeignObject*)foreignObject
|
||||
{
|
||||
if (_delegate != nil && _respondsTo.shouldHandleForeignObject == 1) {
|
||||
return [_delegate svg:self
|
||||
shouldHandleForeignObject:foreignObject];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)svgParser:(IJSVGParser*)parser
|
||||
handleForeignObject:(IJSVGForeignObject*)foreignObject
|
||||
document:(NSXMLDocument*)document
|
||||
{
|
||||
if (_delegate != nil && _respondsTo.handleForeignObject == 1) {
|
||||
[_delegate svg:self
|
||||
handleForeignObject:foreignObject
|
||||
document:document];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark matching
|
||||
|
||||
- (BOOL)matchesPropertiesWithMask:(IJSVGMatchPropertiesMask)mask
|
||||
@@ -1017,7 +946,7 @@
|
||||
IJSVGPath* path = (IJSVGPath*)node;
|
||||
if((mask & IJSVGMatchPropertyContainsStrokedElement) != 0 &&
|
||||
[node isKindOfClass:IJSVGPath.class] == YES &&
|
||||
path.isStroked == YES) {
|
||||
[path matchesTraits:IJSVGNodeTraitStroked] == YES) {
|
||||
matchedMask |= IJSVGMatchPropertyContainsStrokedElement;
|
||||
}
|
||||
|
||||
@@ -1033,7 +962,7 @@
|
||||
*stop = YES;
|
||||
}
|
||||
};
|
||||
[IJSVGNode walkNodeTree:_group
|
||||
[IJSVGNode walkNodeTree:_rootNode
|
||||
handler:handler];
|
||||
return matchedMask == mask;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#import "IJSVGRadialGradient.h"
|
||||
#import "IJSVGShapeLayer.h"
|
||||
#import "IJSVGStrokeLayer.h"
|
||||
#import "IJSVGTransformLayer.h"
|
||||
|
||||
@implementation IJSVGExporter
|
||||
|
||||
@@ -395,7 +396,7 @@ NSString* IJSVGHash(NSString* key)
|
||||
_dom.characterEncoding = XML_DOC_CHARSET;
|
||||
|
||||
// sort out stuff, so here we go...
|
||||
[self _recursiveParseFromLayer:_svg.layer
|
||||
[self _recursiveParseFromLayer:_svg.rootLayer
|
||||
intoElement:nestedRoot];
|
||||
|
||||
// this needs to be added incase it needs to be cleaned
|
||||
@@ -1050,10 +1051,12 @@ NSString* IJSVGHash(NSString* key)
|
||||
if (child != nil) {
|
||||
[element addChild:child];
|
||||
}
|
||||
} else if ([layer isKindOfClass:[IJSVGGroupLayer class]]) {
|
||||
} else if ([layer isKindOfClass:[IJSVGGroupLayer class]] ||
|
||||
[layer isKindOfClass:IJSVGTransformLayer.class]) {
|
||||
// assume its probably a group?
|
||||
NSXMLElement* child = [self elementForGroup:layer
|
||||
fromParent:element];
|
||||
|
||||
if (child != nil) {
|
||||
[element addChild:child];
|
||||
}
|
||||
@@ -1137,6 +1140,8 @@ NSString* IJSVGHash(NSString* key)
|
||||
dict[@"id"] = [self identifierForElement:patternElement];
|
||||
dict[@"width"] = IJSVGShortFloatStringWithOptions(layer.patternNode.width.value, _floatingPointOptions);
|
||||
dict[@"height"] = IJSVGShortFloatStringWithOptions(layer.patternNode.height.value, _floatingPointOptions);
|
||||
dict[@"patternUnits"] = layer.patternNode.units == IJSVGUnitObjectBoundingBox ? @"objectBoundingBox" : @"userSpaceOnUse";
|
||||
dict[@"patternContentUnits"] = layer.patternNode.contentUnits == IJSVGUnitObjectBoundingBox ? @"objectBoundingBox" : @"userSpaceOnUse";
|
||||
|
||||
// sort out x and y position
|
||||
IJSVGUnitLength* x = layer.patternNode.x;
|
||||
@@ -1207,7 +1212,8 @@ NSString* IJSVGHash(NSString* key)
|
||||
@"cy" : [rGradient.cy stringValueWithFloatingPointOptions:_floatingPointOptions],
|
||||
@"fx" : [rGradient.fx stringValueWithFloatingPointOptions:_floatingPointOptions],
|
||||
@"fy" : [rGradient.fy stringValueWithFloatingPointOptions:_floatingPointOptions],
|
||||
@"r" : [rGradient.radius stringValueWithFloatingPointOptions:_floatingPointOptions] };
|
||||
@"r" : [rGradient.r stringValueWithFloatingPointOptions:_floatingPointOptions],
|
||||
@"fr" : [rGradient.fr stringValueWithFloatingPointOptions:_floatingPointOptions] };
|
||||
|
||||
// give it the attributes
|
||||
IJSVGApplyAttributesToElement(dict, gradientElement);
|
||||
@@ -1367,8 +1373,8 @@ NSString* IJSVGHash(NSString* key)
|
||||
CGPathRef path = layer.path;
|
||||
|
||||
// copy the path as we want to translate
|
||||
CGAffineTransform trans = CGAffineTransformMakeTranslation(layer.originalPathOrigin.x,
|
||||
layer.originalPathOrigin.y);
|
||||
CGAffineTransform trans = CGAffineTransformMakeTranslation(layer.frame.origin.x,
|
||||
layer.frame.origin.y);
|
||||
CGPathRef transformPath = CGPathCreateCopyByTransformingPath(path, &trans);
|
||||
|
||||
NSMutableDictionary* dict = [[[NSMutableDictionary alloc] init] autorelease];
|
||||
|
||||
@@ -364,16 +364,16 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
IJSVGExporterPathInstruction* nInstruction = nil;
|
||||
nInstruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'t'
|
||||
dataCount:2] autorelease];
|
||||
nInstruction.data[0] = instruction.data[3];
|
||||
nInstruction.data[1] = instruction.data[4];
|
||||
nInstruction.data[0] = instruction.data[2];
|
||||
nInstruction.data[1] = instruction.data[3];
|
||||
[nInstructions addObject:nInstruction];
|
||||
continue;
|
||||
} else if (lastInstruction.instruction == 't' && instruction.data[2] == lastInstruction.data[0] && instruction.data[3] == lastInstruction.data[1]) {
|
||||
IJSVGExporterPathInstruction* nInstruction = nil;
|
||||
nInstruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'t'
|
||||
dataCount:2] autorelease];
|
||||
nInstruction.data[0] = instruction.data[3];
|
||||
nInstruction.data[1] = instruction.data[4];
|
||||
nInstruction.data[0] = instruction.data[2];
|
||||
nInstruction.data[1] = instruction.data[3];
|
||||
[nInstructions addObject:nInstruction];
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,8 @@
|
||||
@interface IJSVGGradientLayer : IJSVGLayer {
|
||||
}
|
||||
|
||||
@property (nonatomic, assign) CGRect viewBox;
|
||||
@property (nonatomic, retain) IJSVGGradient* gradient;
|
||||
@property (nonatomic, assign) CGAffineTransform absoluteTransform;
|
||||
@property (nonatomic, assign) CGRect objectRect;
|
||||
@property (nonatomic, assign) CGRect viewBox;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
#import "IJSVGGradientLayer.h"
|
||||
#import <IJSVG/IJSVGRootLayer.h>
|
||||
|
||||
@implementation IJSVGGradientLayer
|
||||
|
||||
@@ -16,13 +17,9 @@
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
self.requiresBackingScaleHelp = YES;
|
||||
self.shouldRasterize = YES;
|
||||
}
|
||||
return self;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)setGradient:(IJSVGGradient*)newGradient
|
||||
@@ -74,6 +71,11 @@
|
||||
[super setBackingScaleFactor:backingScaleFactor];
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)referencingLayer
|
||||
{
|
||||
return [super referencingLayer] ?: self.superlayer;
|
||||
}
|
||||
|
||||
- (void)drawInContext:(CGContextRef)ctx
|
||||
{
|
||||
[super drawInContext:ctx];
|
||||
@@ -84,14 +86,22 @@
|
||||
}
|
||||
|
||||
// draw the gradient
|
||||
CGAffineTransform trans = CGAffineTransformMakeTranslation(-CGRectGetMinX(_objectRect),
|
||||
-CGRectGetMinY(_objectRect));
|
||||
CGAffineTransform transform = CGAffineTransformConcat(_absoluteTransform, trans);
|
||||
CALayer<IJSVGDrawableLayer>* layer = (CALayer<IJSVGDrawableLayer>*)self.referencingLayer;
|
||||
CGRect objectRect = layer.boundingBox;
|
||||
CGRect objectFrame = layer.frame;
|
||||
CGAffineTransform affine = [IJSVGLayer absoluteTransformForLayer:layer];
|
||||
affine = CGAffineTransformTranslate(affine,
|
||||
-CGRectGetMinX(objectFrame),
|
||||
-CGRectGetMinY(objectFrame));
|
||||
CGContextSaveGState(ctx);
|
||||
|
||||
IJSVGRootLayer* rootNode = (IJSVGRootLayer*)[IJSVGLayer rootLayerForLayer:self];
|
||||
CGRect bounds = [rootNode.viewBox computeValue:CGSizeZero];
|
||||
|
||||
[self.gradient drawInContextRef:ctx
|
||||
objectRect:_objectRect
|
||||
absoluteTransform:transform
|
||||
viewPort:self.viewBox];
|
||||
objectRect:objectRect
|
||||
absoluteTransform:affine
|
||||
viewPort:bounds];
|
||||
CGContextRestoreGState(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
#import <IJSVG/IJSVGShapeLayer.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
@interface IJSVGGroupLayer : IJSVGLayer
|
||||
@interface IJSVGGroupLayer : IJSVGLayer {
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) IJSVGUnitRect* viewBox;
|
||||
@property (nonatomic, assign) IJSVGViewBoxAlignment viewBoxAlignment;
|
||||
@property (nonatomic, assign) IJSVGViewBoxMeetOrSlice viewBoxMeetOrSlice;
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,7 +7,16 @@
|
||||
//
|
||||
|
||||
#import "IJSVGGroupLayer.h"
|
||||
#import "IJSVGViewBox.h"
|
||||
#import "IJSVGUnitRect.h"
|
||||
#import "IJSVGLayer.h"
|
||||
|
||||
@implementation IJSVGGroupLayer
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)[_viewBox release], _viewBox = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,13 +7,19 @@
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
#import <IJSVG/IJSVGImage.h>
|
||||
#import <IJSVG/IJSVGTransformLayer.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
@interface IJSVGImageLayer : IJSVGLayer {
|
||||
|
||||
@private
|
||||
IJSVGLayer* _imageLayer;
|
||||
}
|
||||
|
||||
- (id)initWithImage:(NSImage*)image;
|
||||
- (id)initWithCGImage:(CGImageRef)imageRef;
|
||||
@property (nonatomic, retain) IJSVGImage* image;
|
||||
|
||||
- (id)initWithImage:(IJSVGImage*)image;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,46 +10,44 @@
|
||||
|
||||
@implementation IJSVGImageLayer
|
||||
|
||||
- (id)initWithImage:(NSImage*)image
|
||||
- (void)dealloc
|
||||
{
|
||||
NSRect rect = (NSRect){
|
||||
.origin = NSZeroPoint,
|
||||
.size = image.size
|
||||
};
|
||||
CGImageRef ref = [image CGImageForProposedRect:&rect
|
||||
context:nil
|
||||
hints:nil];
|
||||
return [self initWithCGImage:ref];
|
||||
(void)[_image release], _image = nil;
|
||||
(void)[_imageLayer release], _imageLayer = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)initWithCGImage:(CGImageRef)imageRef
|
||||
- (id)initWithImage:(IJSVGImage*)image
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
// set the contents
|
||||
self.contents = (id)imageRef;
|
||||
|
||||
// make sure we say we need help
|
||||
self.requiresBackingScaleHelp = YES;
|
||||
self.shouldRasterize = YES;
|
||||
|
||||
// set the frame, simple stuff
|
||||
self.frame = (CGRect){
|
||||
.origin = CGPointZero,
|
||||
.size = CGSizeMake(CGImageGetWidth(imageRef),
|
||||
CGImageGetHeight(imageRef))
|
||||
};
|
||||
if((self = [super init]) != nil) {
|
||||
_image = image.retain;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setNeedsDisplay
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
{
|
||||
// swap the content around on call
|
||||
// because set needs display discards previous
|
||||
// content - yolo!
|
||||
id oldContent = self.contents;
|
||||
[super setNeedsDisplay];
|
||||
self.contents = oldContent;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)layoutSublayers
|
||||
{
|
||||
[super layoutSublayers];
|
||||
[self reloadContent];
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)reloadContent
|
||||
{
|
||||
if(_imageLayer == nil) {
|
||||
_imageLayer = [IJSVGLayer layer].retain;
|
||||
_imageLayer.contentsGravity = kCAGravityResize;
|
||||
_imageLayer.affineTransform = CGAffineTransformMakeScale(1.f, -1.f);
|
||||
_imageLayer.contents = (id)_image.CGImage;
|
||||
[self addSublayer:_imageLayer];
|
||||
}
|
||||
|
||||
_imageLayer.frame = self.bounds;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,8 +15,52 @@
|
||||
@class IJSVGPatternLayer;
|
||||
@class IJSVGStrokeLayer;
|
||||
@class IJSVGGroupLayer;
|
||||
@class IJSVGLayer;
|
||||
|
||||
@interface IJSVGLayer : CALayer {
|
||||
typedef NS_ENUM(NSUInteger, IJSVGLayerFillType) {
|
||||
IJSVGLayerFillTypeColor,
|
||||
IJSVGLayerFillTypePattern,
|
||||
IJSVGLayerFillTypeGradient,
|
||||
IJSVGLayerFillTypeUnknown
|
||||
};
|
||||
|
||||
typedef NS_OPTIONS(NSUInteger, IJSVGLayerTraits) {
|
||||
IJSVGLayerTraitGroup
|
||||
};
|
||||
|
||||
@protocol IJSVGPathableLayer <NSObject>
|
||||
|
||||
@required
|
||||
@property (nonatomic, assign) CGPathRef path;
|
||||
|
||||
@end
|
||||
|
||||
@protocol IJSVGDrawableLayer <NSObject>
|
||||
|
||||
@required
|
||||
@property (nonatomic, assign) CGBlendMode blendingMode;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* clipLayer;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* maskLayer;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule clipRule;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule fillRule;
|
||||
@property (nonatomic, readonly) CGPoint absoluteOrigin;
|
||||
@property (nonatomic, assign) IJSVGRenderQuality renderQuality;
|
||||
@property (nonatomic, assign) CGFloat backingScaleFactor;
|
||||
@property (nonatomic, readonly) BOOL requiresBackingScaleHelp;
|
||||
@property (nonatomic, readonly) CALayer<IJSVGDrawableLayer>* rootLayer;
|
||||
@property (nonatomic, readonly) CGRect absoluteFrame;
|
||||
@property (nonatomic, assign) CGRect boundingBox;
|
||||
@property (nonatomic, readonly) CGRect strokeBoundingBox;
|
||||
@property (nonatomic, readonly) CGRect boundingBoxBounds;
|
||||
@property (nonatomic, assign) CGRect outerBoundingBox;
|
||||
@property (nonatomic, assign) CALayer<IJSVGDrawableLayer>* referencingLayer;
|
||||
@property (nonatomic, readonly) NSArray<CALayer<IJSVGDrawableLayer>*>* debugLayers;
|
||||
|
||||
- (void)performRenderInContext:(CGContextRef)ctx;
|
||||
|
||||
@end
|
||||
|
||||
@interface IJSVGLayer : CALayer <IJSVGDrawableLayer> {
|
||||
|
||||
@private
|
||||
IJSVGLayer* _maskingLayer;
|
||||
@@ -27,19 +71,65 @@
|
||||
@property (nonatomic, assign) IJSVGStrokeLayer* strokeLayer;
|
||||
@property (nonatomic, assign) IJSVGGradientLayer* gradientStrokeLayer;
|
||||
@property (nonatomic, assign) IJSVGPatternLayer* patternStrokeLayer;
|
||||
@property (nonatomic, assign) BOOL requiresBackingScaleHelp;
|
||||
@property (nonatomic, readonly) BOOL requiresBackingScaleHelp;
|
||||
@property (nonatomic, assign) CGFloat backingScaleFactor;
|
||||
@property (nonatomic, assign) IJSVGRenderQuality renderQuality;
|
||||
@property (nonatomic, assign) CGBlendMode blendingMode;
|
||||
@property (nonatomic, assign) CGPoint absoluteOrigin;
|
||||
@property (nonatomic, assign) BOOL convertMasksToPaths;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* clipLayer;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule clipRule;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule fillRule;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* maskLayer;
|
||||
@property (nonatomic, readonly) CALayer<IJSVGDrawableLayer>* rootLayer;
|
||||
@property (nonatomic, readonly) CGRect absoluteFrame;
|
||||
@property (nonatomic, assign) CGRect boundingBox;
|
||||
@property (nonatomic, readonly) CGRect boundingBoxBounds;
|
||||
@property (nonatomic, readonly) CGRect strokeBoundingBox;
|
||||
@property (nonatomic, assign) CGRect outerBoundingBox;
|
||||
@property (nonatomic, readonly) CGRect outerBoundingBoxBounds;
|
||||
@property (nonatomic, assign) CALayer<IJSVGDrawableLayer>* referencingLayer;
|
||||
|
||||
+ (IJSVGLayerFillType)fillTypeForFill:(id)fill;
|
||||
|
||||
+ (NSArray*)deepestSublayersOfLayer:(CALayer*)layer;
|
||||
+ (void)recursivelyWalkLayer:(CALayer*)layer
|
||||
withBlock:(void (^)(CALayer* layer, BOOL isMask, BOOL* stop))block;
|
||||
+ (void)recursivelyWalkLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
withBlock:(void (^)(CALayer<IJSVGDrawableLayer>* layer, BOOL* stop))block;
|
||||
|
||||
- (void)applySublayerMaskToContext:(CGContextRef)context
|
||||
forSublayer:(IJSVGLayer*)sublayer
|
||||
withOffset:(CGPoint)offset;
|
||||
|
||||
+ (CGImageRef)newMaskImageForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
scale:(CGFloat)scale;
|
||||
|
||||
+ (CGImageRef)newImageForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
colorSpace:(CGColorSpaceRef)colorSpace
|
||||
bitmapInfo:(uint32_t)bitmapInfo
|
||||
scale:(CGFloat)scale;
|
||||
|
||||
+ (void)renderLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx;
|
||||
|
||||
+ (void)applyBlendingMode:(CGBlendMode)blendMode
|
||||
toContext:(CGContextRef)ctx
|
||||
drawingBlock:(dispatch_block_t)drawingBlock;
|
||||
|
||||
+ (void)clipContextWithClip:(CALayer<IJSVGDrawableLayer>*)clipLayer
|
||||
toLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx
|
||||
drawingBlock:(dispatch_block_t)drawingBlock;
|
||||
|
||||
+ (void)clipContextWithMask:(CALayer<IJSVGDrawableLayer>*)maskLayer
|
||||
toLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)context
|
||||
drawingBlock:(dispatch_block_t)drawingBlock;
|
||||
|
||||
+ (CALayer<IJSVGDrawableLayer>*)rootLayerForLayer:(CALayer<IJSVGDrawableLayer>*)layer;
|
||||
+ (CGAffineTransform)absoluteTransformForLayer:(CALayer*)layer;
|
||||
+ (CGRect)absoluteFrameForLayer:(CALayer<IJSVGDrawableLayer>*)layer;
|
||||
+ (CGRect)calculateFrameForSublayers:(NSArray<CALayer<IJSVGDrawableLayer>*>*)layers;
|
||||
|
||||
+ (void)logLayer:(CALayer<IJSVGDrawableLayer>*)layer;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,15 +10,255 @@
|
||||
#import "IJSVGGroupLayer.h"
|
||||
#import "IJSVGLayer.h"
|
||||
#import "IJSVGShapeLayer.h"
|
||||
#import "IJSVGTransformLayer.h"
|
||||
#import "IJSVGRootLayer.h"
|
||||
|
||||
@implementation IJSVGLayer
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_clipLayer release]), _clipLayer = nil;
|
||||
(void)([_maskLayer release]), _maskLayer = nil;
|
||||
(void)([_clipRule release]), _clipRule = nil;
|
||||
(void)([_fillRule release]), _fillRule = nil;
|
||||
(void)([_maskingLayer release]), _maskingLayer = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if((self = [super init]) != nil) {
|
||||
_boundingBox = CGRectNull;
|
||||
_outerBoundingBox = CGRectNull;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CAShapeLayerFillRule)fillRule
|
||||
{
|
||||
return kCAFillRuleNonZero;
|
||||
}
|
||||
|
||||
- (CAShapeLayerFillRule)clipRule
|
||||
{
|
||||
if(_clipRule == nil) {
|
||||
return self.fillRule;
|
||||
}
|
||||
return _clipRule;
|
||||
}
|
||||
|
||||
+ (IJSVGLayerFillType)fillTypeForFill:(id)fill
|
||||
{
|
||||
if([fill isKindOfClass:IJSVGColorNode.class]) {
|
||||
return IJSVGLayerFillTypeColor;
|
||||
}
|
||||
if([fill isKindOfClass:IJSVGGradient.class]) {
|
||||
return IJSVGLayerFillTypeGradient;
|
||||
}
|
||||
if([fill isKindOfClass:IJSVGPattern.class]) {
|
||||
return IJSVGLayerFillTypePattern;
|
||||
}
|
||||
return IJSVGLayerFillTypeUnknown;
|
||||
}
|
||||
|
||||
+ (CGAffineTransform)absoluteTransformForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
{
|
||||
CGAffineTransform identity = CGAffineTransformIdentity;
|
||||
CALayer<IJSVGDrawableLayer>* parentLayer = layer;
|
||||
while((parentLayer = parentLayer.referencingLayer) != nil) {
|
||||
identity = [self absoluteTransformForLayer:parentLayer];
|
||||
|
||||
// only go up until we find a root layer, at that point, we know
|
||||
// we can stop looking
|
||||
if([parentLayer isKindOfClass:IJSVGRootLayer.class] == YES) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return CGAffineTransformConcat(identity, layer.affineTransform);
|
||||
}
|
||||
|
||||
+ (CALayer<IJSVGDrawableLayer>*)rootLayerForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
{
|
||||
CALayer<IJSVGDrawableLayer>* parentLayer = (CALayer<IJSVGDrawableLayer>*)layer.referencingLayer;
|
||||
while([parentLayer isKindOfClass:IJSVGRootLayer.class] == NO &&
|
||||
parentLayer.referencingLayer != nil) {
|
||||
parentLayer = (CALayer<IJSVGDrawableLayer>*)parentLayer.referencingLayer;
|
||||
}
|
||||
return parentLayer;
|
||||
}
|
||||
|
||||
+ (void)renderLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx
|
||||
{
|
||||
dispatch_block_t drawingBlock = ^{
|
||||
[layer performRenderInContext:ctx];
|
||||
};
|
||||
[self applyBlendingMode:layer.blendingMode
|
||||
toContext:ctx
|
||||
drawingBlock:^{
|
||||
// we need to clip first
|
||||
if(layer.clipLayer == nil) {
|
||||
drawingBlock();
|
||||
return;
|
||||
}
|
||||
[self clipContextWithClip:layer.clipLayer
|
||||
toLayer:layer
|
||||
inContext:ctx
|
||||
drawingBlock:drawingBlock];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)applyBlendingMode:(CGBlendMode)blendMode
|
||||
toContext:(CGContextRef)ctx
|
||||
drawingBlock:(dispatch_block_t)drawingBlock
|
||||
{
|
||||
if (blendMode != kCGBlendModeNormal) {
|
||||
CGContextSaveGState(ctx);
|
||||
CGContextSetBlendMode(ctx, blendMode);
|
||||
drawingBlock();
|
||||
CGContextRestoreGState(ctx);
|
||||
return;
|
||||
}
|
||||
drawingBlock();
|
||||
}
|
||||
|
||||
/// Shape layers are the only thing we can clip, as they contain a path, however
|
||||
/// the layer passed to us from a clip could have groups contained with in it that
|
||||
/// have transforms on them, so simply recursively iterate over them and concat
|
||||
/// their transforms down to the path and clip at the end with the path.
|
||||
+ (void)recursivelyClip:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
transform:(CGAffineTransform)transform
|
||||
inContext:(CGContextRef)ctx
|
||||
{
|
||||
if([layer isKindOfClass:IJSVGShapeLayer.class]) {
|
||||
[self clipContextWithShapeLayer:(IJSVGShapeLayer*)layer
|
||||
transform:transform
|
||||
inContext:ctx];
|
||||
return;
|
||||
}
|
||||
|
||||
for(CALayer<IJSVGDrawableLayer>* drawableLayer in layer.sublayers) {
|
||||
CGAffineTransform drawTransform = CGAffineTransformConcat(transform,
|
||||
drawableLayer.affineTransform);
|
||||
|
||||
// If its not a shape layer, just go down the tree until we find one
|
||||
if([drawableLayer isKindOfClass:IJSVGShapeLayer.class] == NO) {
|
||||
[self recursivelyClip:drawableLayer
|
||||
transform:drawTransform
|
||||
inContext:ctx];
|
||||
continue;
|
||||
}
|
||||
IJSVGShapeLayer* shapeLayer = (IJSVGShapeLayer*)drawableLayer;
|
||||
[self clipContextWithShapeLayer:shapeLayer
|
||||
transform:transform
|
||||
inContext:ctx];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)clipContextWithShapeLayer:(IJSVGShapeLayer*)shapeLayer
|
||||
transform:(CGAffineTransform)transform
|
||||
inContext:(CGContextRef)ctx
|
||||
{
|
||||
CGAffineTransform drawTransform = CGAffineTransformConcat(transform,
|
||||
shapeLayer.affineTransform);
|
||||
// Shape layers paths are reset back to 0,0 origin, so in order to be
|
||||
// correct path, we need to shift it back to where it belongs.
|
||||
drawTransform = CGAffineTransformTranslate(transform,
|
||||
shapeLayer.frame.origin.x,
|
||||
shapeLayer.frame.origin.y);
|
||||
CGPathRef path = CGPathCreateCopyByTransformingPath(shapeLayer.path,
|
||||
&drawTransform);
|
||||
CGContextAddPath(ctx, path);
|
||||
CGPathRelease(path);
|
||||
}
|
||||
|
||||
+ (void)clipContextWithClip:(CALayer<IJSVGDrawableLayer>*)clipLayer
|
||||
toLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx
|
||||
drawingBlock:(dispatch_block_t)drawingBlock
|
||||
{
|
||||
CGContextSaveGState(ctx);
|
||||
[self recursivelyClip:clipLayer
|
||||
transform:CGAffineTransformIdentity
|
||||
inContext:ctx];
|
||||
if([layer.clipRule isEqualToString:kCAFillRuleEvenOdd]) {
|
||||
CGContextEOClip(ctx);
|
||||
} else {
|
||||
CGContextClip(ctx);
|
||||
}
|
||||
drawingBlock();
|
||||
CGContextRestoreGState(ctx);
|
||||
}
|
||||
|
||||
+ (void)clipContextWithMask:(CALayer<IJSVGDrawableLayer>*)maskLayer
|
||||
toLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx
|
||||
drawingBlock:(dispatch_block_t)drawingBlock
|
||||
{
|
||||
CGContextSaveGState(ctx);
|
||||
CGRect bounds = layer.outerBoundingBox;
|
||||
CGFloat scale = layer.backingScaleFactor;
|
||||
CGImageRef maskImage = [self newMaskImageForLayer:maskLayer
|
||||
scale:scale];
|
||||
CGContextClipToMask(ctx, bounds, maskImage);
|
||||
drawingBlock();
|
||||
CGImageRelease(maskImage);
|
||||
CGContextRestoreGState(ctx);
|
||||
}
|
||||
|
||||
+ (CGImageRef)newMaskImageForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
scale:(CGFloat)scale
|
||||
{
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
CGImageRef ref = [self newImageForLayer:layer
|
||||
colorSpace:colorSpace
|
||||
bitmapInfo:kCGImageAlphaNone
|
||||
scale:scale];
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
return ref;
|
||||
}
|
||||
|
||||
+ (CGImageRef)newImageForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
colorSpace:(CGColorSpaceRef)colorSpace
|
||||
bitmapInfo:(uint32_t)bitmapInfo
|
||||
scale:(CGFloat)scale
|
||||
{
|
||||
CGRect frame = layer.outerBoundingBox;
|
||||
CGContextRef offscreenContext = CGBitmapContextCreate(NULL,
|
||||
ceilf(frame.size.width * scale),
|
||||
ceilf(frame.size.height * scale),
|
||||
8, 0, colorSpace, bitmapInfo);
|
||||
|
||||
CGContextSaveGState(offscreenContext);
|
||||
CGContextScaleCTM(offscreenContext, scale, scale);
|
||||
CGContextTranslateCTM(offscreenContext, -frame.origin.x, -frame.origin.y);
|
||||
[layer renderInContext:offscreenContext];
|
||||
CGImageRef image = CGBitmapContextCreateImage(offscreenContext);
|
||||
CGContextRelease(offscreenContext);
|
||||
return image;
|
||||
}
|
||||
|
||||
+ (CGRect)absoluteFrameForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
{
|
||||
return (CGRect) {
|
||||
.origin = [self absoluteOriginForLayer:layer],
|
||||
.size = layer.frame.size
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGPoint)absoluteOriginForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
{
|
||||
CGPoint point = CGPointZero;
|
||||
CALayer<IJSVGDrawableLayer>* pLayer = layer;
|
||||
while (pLayer != nil) {
|
||||
point.x += pLayer.frame.origin.x;
|
||||
point.y += pLayer.frame.origin.y;
|
||||
pLayer = pLayer.referencingLayer;
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
+ (NSArray*)deepestSublayersOfLayer:(CALayer*)layer
|
||||
{
|
||||
NSMutableArray* arr = [[[NSMutableArray alloc] init] autorelease];
|
||||
@@ -33,51 +273,90 @@
|
||||
return arr;
|
||||
}
|
||||
|
||||
+ (void)recursivelyWalkLayer:(CALayer*)layer
|
||||
withBlock:(void (^)(CALayer* layer, BOOL isMask, BOOL* stop))block
|
||||
+ (void)recursivelyWalkLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
withBlock:(void (^)(CALayer<IJSVGDrawableLayer>* layer, BOOL* stop))block
|
||||
{
|
||||
// call for layer and mask if there is one
|
||||
BOOL stop = NO;
|
||||
block(layer, NO, &stop);
|
||||
block(layer, &stop);
|
||||
if(stop == YES) {
|
||||
return;
|
||||
}
|
||||
|
||||
// do the mask too!
|
||||
if (layer.mask != nil) {
|
||||
block(layer.mask, YES, &stop);
|
||||
if(stop == YES) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// sublayers!!
|
||||
for (CALayer* aLayer in layer.sublayers) {
|
||||
for (CALayer<IJSVGDrawableLayer>* aLayer in layer.sublayers) {
|
||||
[self recursivelyWalkLayer:aLayer
|
||||
withBlock:block];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)logLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
{
|
||||
[self logLayer:layer
|
||||
depth:0];
|
||||
}
|
||||
|
||||
+ (void)logLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
depth:(NSUInteger)depth
|
||||
{
|
||||
NSLog(@"%@ %@ frame: %@ transform: %@",[@"" stringByPaddingToLength:depth
|
||||
withString:@"- - "
|
||||
startingAtIndex:0], layer,
|
||||
NSStringFromRect(layer.frame),
|
||||
[IJSVGTransform affineTransformToSVGTransformComponentString:layer.affineTransform]);
|
||||
for(CALayer<IJSVGDrawableLayer>* sublayer in layer.debugLayers) {
|
||||
[self logLayer:sublayer
|
||||
depth:depth+1];
|
||||
}
|
||||
}
|
||||
|
||||
+ (CGRect)calculateFrameForSublayers:(NSArray<CALayer<IJSVGDrawableLayer>*>*)layers
|
||||
{
|
||||
CGRect rect = CGRectNull;
|
||||
for(CALayer<IJSVGDrawableLayer>* layer in layers) {
|
||||
CGRect layerFrame = layer.outerBoundingBox;
|
||||
// if we are a transform layer, we can just apply its transform
|
||||
// to its sublayers and keep going down the tree
|
||||
if([layer isKindOfClass:IJSVGTransformLayer.class] == YES) {
|
||||
CGRect frame = [self calculateFrameForSublayers:layer.sublayers];
|
||||
frame = CGRectApplyAffineTransform(frame, layer.affineTransform);
|
||||
layerFrame = frame;
|
||||
}
|
||||
if(CGRectIsNull(rect)) {
|
||||
rect = layerFrame;
|
||||
continue;
|
||||
}
|
||||
rect = CGRectUnion(rect, layerFrame);
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (void)setBackingScaleFactor:(CGFloat)newFactor
|
||||
{
|
||||
if (_backingScaleFactor == newFactor) {
|
||||
return;
|
||||
}
|
||||
|
||||
_backingScaleFactor = newFactor;
|
||||
self.contentsScale = newFactor;
|
||||
self.rasterizationScale = newFactor;
|
||||
|
||||
// make sure its applied to any mask or clipPath
|
||||
_maskLayer.backingScaleFactor = newFactor;
|
||||
_clipLayer.backingScaleFactor = newFactor;
|
||||
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)_customRenderInContext:(CGContextRef)ctx
|
||||
- (void)performRenderInContext:(CGContextRef)ctx
|
||||
{
|
||||
if (_convertMasksToPaths == YES && _maskingLayer != nil) {
|
||||
CGContextSaveGState(ctx);
|
||||
[self applySublayerMaskToContext:ctx
|
||||
forSublayer:(IJSVGLayer*)self
|
||||
withOffset:CGPointZero];
|
||||
[super renderInContext:ctx];
|
||||
CGContextRestoreGState(ctx);
|
||||
if(_maskLayer != nil) {
|
||||
[self.class clipContextWithMask:_maskLayer
|
||||
toLayer:self
|
||||
inContext:ctx
|
||||
drawingBlock:^{
|
||||
[super renderInContext:ctx];
|
||||
}];
|
||||
return;
|
||||
}
|
||||
[super renderInContext:ctx];
|
||||
@@ -141,6 +420,21 @@
|
||||
CGContextConcatCTM(context, sublayerTransform);
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)rootLayer
|
||||
{
|
||||
return [self.class rootLayerForLayer:self];
|
||||
}
|
||||
|
||||
- (CGAffineTransform)absoluteTransform
|
||||
{
|
||||
return [IJSVGLayer absoluteTransformForLayer:self];
|
||||
}
|
||||
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
{
|
||||
return _maskLayer != nil || _clipLayer != nil;
|
||||
}
|
||||
|
||||
- (IJSVGShapeLayer*)maskingLayer
|
||||
{
|
||||
return (IJSVGShapeLayer*)_maskingLayer ?: nil;
|
||||
@@ -148,14 +442,8 @@
|
||||
|
||||
- (void)renderInContext:(CGContextRef)ctx
|
||||
{
|
||||
if (_blendingMode != kCGBlendModeNormal) {
|
||||
CGContextSaveGState(ctx);
|
||||
CGContextSetBlendMode(ctx, _blendingMode);
|
||||
[self _customRenderInContext:ctx];
|
||||
CGContextRestoreGState(ctx);
|
||||
return;
|
||||
}
|
||||
[self _customRenderInContext:ctx];
|
||||
[IJSVGLayer renderLayer:self
|
||||
inContext:ctx];
|
||||
}
|
||||
|
||||
- (id<CAAction>)actionForKey:(NSString*)event
|
||||
@@ -163,4 +451,50 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (CGRect)absoluteFrame
|
||||
{
|
||||
return [self.class absoluteFrameForLayer:self];
|
||||
}
|
||||
|
||||
- (CGRect)boundingBox
|
||||
{
|
||||
return CGRectIsNull(_boundingBox) == NO ? _boundingBox : self.frame;
|
||||
}
|
||||
|
||||
- (CGRect)outerBoundingBox
|
||||
{
|
||||
return CGRectIsNull(_outerBoundingBox) == NO ? _outerBoundingBox : self.frame;
|
||||
}
|
||||
|
||||
- (CGRect)outerBoundingBoxBounds
|
||||
{
|
||||
return (CGRect) {
|
||||
.origin = CGPointZero,
|
||||
.size = self.outerBoundingBox.size
|
||||
};
|
||||
}
|
||||
|
||||
- (CGRect)boundingBoxBounds
|
||||
{
|
||||
return (CGRect) {
|
||||
.origin = CGPointZero,
|
||||
.size = self.boundingBox.size
|
||||
};
|
||||
}
|
||||
|
||||
- (CGRect)strokeBoundingBox
|
||||
{
|
||||
return self.boundingBox;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)referencingLayer
|
||||
{
|
||||
return _referencingLayer ?: self.superlayer;
|
||||
}
|
||||
|
||||
-(NSArray<CALayer<IJSVGDrawableLayer>*>*)debugLayers
|
||||
{
|
||||
return self.sublayers;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
@interface IJSVGPatternLayer : IJSVGLayer
|
||||
|
||||
@property (nonatomic, retain) IJSVGLayer* pattern;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* pattern;
|
||||
@property (nonatomic, retain) IJSVGPattern* patternNode;
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,7 +6,17 @@
|
||||
// Copyright © 2017 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGPatternLayer.h"
|
||||
#import <IJSVG/IJSVGPatternLayer.h>
|
||||
#import <IJSVG/IJSVGTransform.h>
|
||||
#import <IJSVG/IJSVGUnitRect.h>
|
||||
#import <IJSVG/IJSVGViewBox.h>
|
||||
|
||||
@interface IJSVGPatternLayer ()
|
||||
|
||||
@property (nonatomic, assign, readonly) CGSize cellSize;
|
||||
@property (nonatomic, assign) CGRect viewBox;
|
||||
|
||||
@end
|
||||
|
||||
@implementation IJSVGPatternLayer
|
||||
|
||||
@@ -17,22 +27,40 @@
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
self.requiresBackingScaleHelp = YES;
|
||||
self.shouldRasterize = YES;
|
||||
}
|
||||
return self;
|
||||
return YES;
|
||||
}
|
||||
|
||||
void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
|
||||
{
|
||||
// reassign the layer
|
||||
IJSVGPatternLayer* layer = (IJSVGPatternLayer*)info;
|
||||
[layer.pattern renderInContext:ctx];
|
||||
CGSize size = layer.cellSize;
|
||||
CGContextSaveGState(ctx);
|
||||
CGRect rect = CGRectMake(0.f, 0.f, size.width, size.height);
|
||||
CGContextClipToRect(ctx, rect);
|
||||
|
||||
IJSVGViewBoxAlignment alignment = layer.patternNode.viewBoxAlignment;
|
||||
IJSVGViewBoxMeetOrSlice meetOrSlice = layer.patternNode.viewBoxMeetOrSlice;
|
||||
CGRect viewBox = layer.viewBox;
|
||||
|
||||
[IJSVGViewBox drawViewBox:viewBox
|
||||
inRect:rect
|
||||
alignment:alignment
|
||||
meetOrSlice:meetOrSlice
|
||||
inContext:ctx
|
||||
drawingBlock:^(CGSize size) {
|
||||
[layer.pattern renderInContext:ctx];
|
||||
}];
|
||||
CGContextSaveGState(ctx);
|
||||
};
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)referencingLayer
|
||||
{
|
||||
return [super referencingLayer] ?: self.superlayer;
|
||||
}
|
||||
|
||||
- (void)drawInContext:(CGContextRef)ctx
|
||||
{
|
||||
// holder for callback
|
||||
@@ -42,13 +70,54 @@ void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
|
||||
CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
|
||||
CGContextSetFillColorSpace(ctx, patternSpace);
|
||||
CGColorSpaceRelease(patternSpace);
|
||||
|
||||
CGRect rect = self.referencingLayer.boundingBoxBounds;
|
||||
|
||||
IJSVGUnitLength* wLength = _patternNode.width;
|
||||
IJSVGUnitLength* hLength = _patternNode.height;
|
||||
|
||||
if(self.patternNode.units == IJSVGUnitObjectBoundingBox ||
|
||||
self.patternNode.contentUnits == IJSVGUnitObjectBoundingBox) {
|
||||
wLength = wLength.lengthByMatchingPercentage;
|
||||
hLength = hLength.lengthByMatchingPercentage;
|
||||
}
|
||||
|
||||
CGFloat width = [wLength computeValue:rect.size.width];
|
||||
CGFloat height = [hLength computeValue:rect.size.height];
|
||||
_cellSize = CGSizeMake(width, height);
|
||||
|
||||
CALayer<IJSVGDrawableLayer>* layer = (CALayer<IJSVGDrawableLayer>*)self.referencingLayer;
|
||||
|
||||
// transform us back into the correct space
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
if (self.patternNode.units == IJSVGUnitUserSpaceOnUse) {
|
||||
CGRect frame = layer.boundingBox;
|
||||
transform = [IJSVGLayer absoluteTransformForLayer:layer];
|
||||
transform = CGAffineTransformTranslate(transform,
|
||||
-CGRectGetMinX(frame),
|
||||
-CGRectGetMinY(frame));
|
||||
}
|
||||
|
||||
transform = CGAffineTransformConcat(transform, IJSVGConcatTransforms(self.patternNode.transforms));
|
||||
// transform the X and Y shift
|
||||
transform = CGAffineTransformTranslate(transform,
|
||||
[_patternNode.x computeValue:rect.size.width],
|
||||
[_patternNode.y computeValue:rect.size.height]);
|
||||
|
||||
// who knew that patterns have viewBoxes? Not me, but here is an implementation
|
||||
// of it anyway
|
||||
if(_patternNode.viewBox != nil && _patternNode.viewBox.isZeroRect == NO) {
|
||||
if(_patternNode.units == IJSVGUnitObjectBoundingBox) {
|
||||
IJSVGUnitRect* viewBox = nil;
|
||||
viewBox = [[_patternNode.viewBox copyByConvertingToUnitsLengthType:IJSVGUnitLengthTypePercentage] autorelease];
|
||||
_viewBox = [viewBox computeValue:rect.size];
|
||||
}
|
||||
}
|
||||
|
||||
// create the pattern
|
||||
CGRect rect = self.bounds;
|
||||
CGPatternRef ref = CGPatternCreate((void*)self, self.bounds,
|
||||
CGAffineTransformIdentity,
|
||||
roundf(rect.size.width * _patternNode.width.value),
|
||||
roundf(rect.size.height * _patternNode.height.value),
|
||||
CGRect selfBounds = self.boundingBoxBounds;
|
||||
CGPatternRef ref = CGPatternCreate((void*)self, selfBounds,
|
||||
transform, width, height,
|
||||
kCGPatternTilingConstantSpacing,
|
||||
true, &callbacks);
|
||||
|
||||
@@ -58,7 +127,12 @@ void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
|
||||
CGPatternRelease(ref);
|
||||
|
||||
// fill it
|
||||
CGContextFillRect(ctx, rect);
|
||||
CGContextFillRect(ctx, selfBounds);
|
||||
}
|
||||
|
||||
- (NSArray<CALayer<IJSVGDrawableLayer>*>*)debugLayers
|
||||
{
|
||||
return @[self.pattern];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// IJSVGRootLayer.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 15/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVG.h>
|
||||
|
||||
@interface IJSVGRootLayer : IJSVGGroupLayer {
|
||||
|
||||
@private
|
||||
BOOL _disableBackingScalePropagation;
|
||||
|
||||
}
|
||||
|
||||
- (void)renderInContext:(CGContextRef)ctx
|
||||
viewPort:(CGRect)viewPort
|
||||
backingScale:(CGFloat)backingScale
|
||||
quality:(IJSVGRenderQuality)quality;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// IJSVGRootLayer.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 15/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGRootLayer.h"
|
||||
|
||||
@implementation IJSVGRootLayer
|
||||
|
||||
- (void)performRenderInContext:(CGContextRef)ctx
|
||||
{
|
||||
if(self.viewBox != nil) {
|
||||
CGRect viewBox = [self.viewBox computeValue:CGSizeZero];
|
||||
__block IJSVGRootLayer* weakSelf = self;
|
||||
IJSVGViewBoxDrawingBlock drawingBlock = ^(CGSize size) {
|
||||
// we have to make sure we set the backing scale factor once
|
||||
// we know how scale this will be drawn at
|
||||
weakSelf.backingScaleFactor *= MAX(size.width, size.height);
|
||||
[super performRenderInContext:ctx];
|
||||
};
|
||||
[IJSVGViewBox drawViewBox:viewBox
|
||||
inRect:self.boundingBoxBounds
|
||||
alignment:self.viewBoxAlignment
|
||||
meetOrSlice:self.viewBoxMeetOrSlice
|
||||
inContext:ctx
|
||||
drawingBlock:drawingBlock];
|
||||
return;
|
||||
}
|
||||
[super performRenderInContext:ctx];
|
||||
}
|
||||
|
||||
- (void)setBackingScaleFactor:(CGFloat)backingScaleFactor
|
||||
{
|
||||
[super setBackingScaleFactor:backingScaleFactor];
|
||||
if(_disableBackingScalePropagation == YES) {
|
||||
return;
|
||||
}
|
||||
[self propagateBackingScalePropertiesToSublayers];
|
||||
}
|
||||
|
||||
- (void)propagateBackingScalePropertiesToSublayers
|
||||
{
|
||||
__block IJSVGRootLayer* weakSelf = self;
|
||||
for(CALayer<IJSVGDrawableLayer>* layer in self.sublayers) {
|
||||
[IJSVGLayer recursivelyWalkLayer:layer
|
||||
withBlock:^(CALayer<IJSVGDrawableLayer>* propLayer, BOOL *stop) {
|
||||
propLayer.renderQuality = weakSelf.renderQuality;
|
||||
propLayer.backingScaleFactor = weakSelf.backingScaleFactor;
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)renderInContext:(CGContextRef)ctx
|
||||
viewPort:(CGRect)viewPort
|
||||
backingScale:(CGFloat)backingScale
|
||||
quality:(IJSVGRenderQuality)quality
|
||||
{
|
||||
CGRect frame = viewPort;
|
||||
self.frame = frame;
|
||||
_disableBackingScalePropagation = YES;
|
||||
self.backingScaleFactor = backingScale;
|
||||
self.renderQuality = quality;
|
||||
_disableBackingScalePropagation = NO;
|
||||
[self propagateBackingScalePropertiesToSublayers];
|
||||
[self renderInContext:ctx];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -10,7 +10,7 @@
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
@interface IJSVGShapeLayer : CAShapeLayer {
|
||||
@interface IJSVGShapeLayer : CAShapeLayer <IJSVGDrawableLayer, IJSVGPathableLayer> {
|
||||
|
||||
@private
|
||||
IJSVGLayer* _maskingLayer;
|
||||
@@ -21,14 +21,25 @@
|
||||
@property (nonatomic, assign) IJSVGStrokeLayer* strokeLayer;
|
||||
@property (nonatomic, assign) IJSVGGradientLayer* gradientStrokeLayer;
|
||||
@property (nonatomic, assign) IJSVGPatternLayer* patternStrokeLayer;
|
||||
@property (nonatomic, assign) BOOL requiresBackingScaleHelp;
|
||||
@property (nonatomic, assign) CGFloat backingScaleFactor;
|
||||
@property (nonatomic, readonly) BOOL requiresBackingScaleHelp;
|
||||
@property (nonatomic, assign) IJSVGRenderQuality renderQuality;
|
||||
@property (nonatomic, assign) CGBlendMode blendingMode;
|
||||
@property (nonatomic, assign) CGPoint absoluteOrigin;
|
||||
@property (nonatomic, assign) CGPoint originalPathOrigin;
|
||||
@property (nonatomic, assign) BOOL convertMasksToPaths;
|
||||
@property (nonatomic, assign) IJSVGPrimitivePathType primitiveType;
|
||||
@property (nonatomic, readonly) CGRect computedFrame;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* clipLayer;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* maskLayer;
|
||||
@property (nonatomic, readonly) CALayer<IJSVGDrawableLayer>* rootLayer;
|
||||
@property (nonatomic, readonly) CGRect absoluteFrame;
|
||||
@property (nonatomic, assign) CGRect boundingBox;
|
||||
@property (nonatomic, assign) CGRect outerBoundingBox;
|
||||
@property (nonatomic, readonly) CGRect boundingBoxBounds;
|
||||
@property (nonatomic, assign) CALayer<IJSVGDrawableLayer>* referencingLayer;
|
||||
@property (nonatomic, assign) CGRect strokeBoundingBox;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule clipRule;
|
||||
|
||||
- (void)applySublayerMaskToContext:(CGContextRef)context
|
||||
forSublayer:(IJSVGLayer*)sublayer
|
||||
|
||||
@@ -13,30 +13,72 @@
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_clipLayer release]), _clipLayer = nil;
|
||||
(void)([_maskLayer release]), _maskLayer = nil;
|
||||
(void)([_maskingLayer release]), _maskingLayer = nil;
|
||||
(void)([_clipRule release]), _clipRule = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)rootLayer
|
||||
{
|
||||
return [IJSVGLayer rootLayerForLayer:self];
|
||||
}
|
||||
|
||||
- (CGRect)absoluteFrame
|
||||
{
|
||||
return [IJSVGLayer absoluteFrameForLayer:self];
|
||||
}
|
||||
|
||||
- (CGAffineTransform)absoluteTransform
|
||||
{
|
||||
return [IJSVGLayer absoluteTransformForLayer:self];
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)referencingLayer
|
||||
{
|
||||
return _referencingLayer ?: self.superlayer;
|
||||
}
|
||||
|
||||
- (CGRect)boundingBoxBounds
|
||||
{
|
||||
return (CGRect) {
|
||||
.origin = CGPointZero,
|
||||
.size = self.boundingBox.size
|
||||
};
|
||||
}
|
||||
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
{
|
||||
return _maskLayer != nil || _clipLayer != nil;
|
||||
}
|
||||
|
||||
- (void)setBackingScaleFactor:(CGFloat)newFactor
|
||||
{
|
||||
if (self.backingScaleFactor == newFactor) {
|
||||
if (_backingScaleFactor == newFactor) {
|
||||
return;
|
||||
}
|
||||
|
||||
_backingScaleFactor = newFactor;
|
||||
self.contentsScale = newFactor;
|
||||
self.rasterizationScale = newFactor;
|
||||
|
||||
// make sure its applied to any mask or clipPath
|
||||
_maskLayer.backingScaleFactor = newFactor;
|
||||
_clipLayer.backingScaleFactor = newFactor;
|
||||
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)_customRenderInContext:(CGContextRef)ctx
|
||||
- (void)performRenderInContext:(CGContextRef)ctx
|
||||
{
|
||||
if (self.convertMasksToPaths == YES && _maskingLayer != nil) {
|
||||
CGContextSaveGState(ctx);
|
||||
[self applySublayerMaskToContext:ctx
|
||||
forSublayer:(IJSVGLayer*)self
|
||||
withOffset:CGPointZero];
|
||||
[super renderInContext:ctx];
|
||||
CGContextRestoreGState(ctx);
|
||||
if(_maskLayer != nil) {
|
||||
[IJSVGLayer clipContextWithMask:_maskLayer
|
||||
toLayer:self
|
||||
inContext:ctx
|
||||
drawingBlock:^{
|
||||
[super renderInContext:ctx];
|
||||
}];
|
||||
return;
|
||||
}
|
||||
[super renderInContext:ctx];
|
||||
@@ -107,26 +149,8 @@
|
||||
|
||||
- (void)renderInContext:(CGContextRef)ctx
|
||||
{
|
||||
if (self.blendingMode != kCGBlendModeNormal) {
|
||||
CGContextSaveGState(ctx);
|
||||
CGContextSetBlendMode(ctx, self.blendingMode);
|
||||
[self _customRenderInContext:ctx];
|
||||
CGContextRestoreGState(ctx);
|
||||
return;
|
||||
}
|
||||
[self _customRenderInContext:ctx];
|
||||
}
|
||||
|
||||
- (CGPoint)absoluteOrigin
|
||||
{
|
||||
CGPoint point = CGPointZero;
|
||||
CALayer* pLayer = self;
|
||||
while (pLayer != nil) {
|
||||
point.x += pLayer.frame.origin.x;
|
||||
point.y += pLayer.frame.origin.y;
|
||||
pLayer = pLayer.superlayer;
|
||||
}
|
||||
return point;
|
||||
[IJSVGLayer renderLayer:(IJSVGLayer*)self
|
||||
inContext:ctx];
|
||||
}
|
||||
|
||||
- (id<CAAction>)actionForKey:(NSString*)event
|
||||
@@ -134,4 +158,9 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(NSArray<CALayer<IJSVGDrawableLayer>*>*)debugLayers
|
||||
{
|
||||
return self.sublayers;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,4 +10,11 @@
|
||||
|
||||
@implementation IJSVGStrokeLayer
|
||||
|
||||
- (CGRect)outerBoundingBox
|
||||
{
|
||||
return CGRectMake(-self.lineWidth / 2.f, -self.lineWidth / 2.f,
|
||||
self.boundingBox.size.width + self.lineWidth,
|
||||
self.boundingBox.size.height + self.lineWidth);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// IJSVGTransformLayer.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 31/03/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
|
||||
@interface IJSVGTransformLayer : CATransformLayer <IJSVGDrawableLayer>
|
||||
|
||||
@property (nonatomic, assign) CGBlendMode blendingMode;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* clipLayer;
|
||||
@property (nonatomic, readonly) CGPoint absoluteOrigin;
|
||||
@property (nonatomic, readonly) CGRect computedFrame;
|
||||
@property (nonatomic, readonly) CALayer<IJSVGDrawableLayer>* referencedLayer;
|
||||
@property (nonatomic, assign) CALayer<IJSVGDrawableLayer>* referencingLayer;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// IJSVGTransformLayer.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 31/03/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGTransformLayer.h"
|
||||
|
||||
@implementation IJSVGTransformLayer
|
||||
|
||||
@synthesize backingScaleFactor;
|
||||
@synthesize renderQuality;
|
||||
@synthesize requiresBackingScaleHelp;
|
||||
@synthesize maskLayer = _maskLayer;
|
||||
@synthesize fillRule = _fillRule;
|
||||
@synthesize clipRule = _clipRule;
|
||||
@synthesize absoluteFrame;
|
||||
@synthesize boundingBox;
|
||||
@synthesize boundingBoxBounds;
|
||||
@synthesize strokeBoundingBox;
|
||||
@synthesize outerBoundingBox;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)[_maskLayer release], _maskLayer = nil;
|
||||
(void)[_fillRule release], _fillRule = nil;
|
||||
(void)[_clipRule release], _clipRule = nil;
|
||||
(void)[_clipLayer release], _clipLayer = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)referencedLayer
|
||||
{
|
||||
return self.sublayers.firstObject;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)referencingLayer {
|
||||
return _referencingLayer ?: self.superlayer;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)rootLayer
|
||||
{
|
||||
return [IJSVGLayer rootLayerForLayer:self];
|
||||
}
|
||||
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)renderInContext:(CGContextRef)ctx
|
||||
{
|
||||
[IJSVGLayer renderLayer:self
|
||||
inContext:ctx];
|
||||
}
|
||||
|
||||
- (void)performRenderInContext:(CGContextRef)ctx
|
||||
{
|
||||
[super renderInContext:ctx];
|
||||
}
|
||||
|
||||
- (NSArray<CALayer<IJSVGDrawableLayer>*>*)debugLayers
|
||||
{
|
||||
return self.sublayers;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// IJSVGColorNode.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 29/03/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGNode.h>
|
||||
|
||||
@interface IJSVGColorNode : IJSVGNode {
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) NSColor* color;
|
||||
|
||||
+ (IJSVGNode*)colorNodeWithColor:(NSColor*)color;
|
||||
|
||||
- (id)initWithColor:(NSColor*)color;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// IJSVGColorNode.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 29/03/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGColorNode.h"
|
||||
|
||||
@implementation IJSVGColorNode
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)[_color release], _color = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
+ (IJSVGNode*)colorNodeWithColor:(NSColor *)color
|
||||
{
|
||||
return [[[self alloc] initWithColor:color] autorelease];
|
||||
}
|
||||
|
||||
- (id)initWithColor:(NSColor*)color {
|
||||
if((self = [super init]) != nil) {
|
||||
[self addTraits:IJSVGNodeTraitPaintable];
|
||||
self.color = color;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)applyPropertiesFromNode:(IJSVGNode*)node
|
||||
{
|
||||
if([node isKindOfClass:self.class]) {
|
||||
self.color = ((IJSVGColorNode*)node).color;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -6,11 +6,11 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <IJSVG/IJSVGColorList.h>
|
||||
#import <IJSVG/IJSVGDef.h>
|
||||
#import <IJSVG/IJSVGTransform.h>
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGGradient : IJSVGGroup
|
||||
|
||||
|
||||
@@ -47,13 +47,13 @@
|
||||
+ (CGFloat *)computeColorStops:(IJSVGGradient*)gradient
|
||||
colors:(NSArray**)someColors
|
||||
{
|
||||
NSArray<IJSVGNode*>* stops = gradient.childNodes;
|
||||
NSArray<IJSVGNode*>* stops = gradient.children;
|
||||
NSMutableArray* colors = [[[NSMutableArray alloc] initWithCapacity:stops.count] autorelease];
|
||||
CGFloat* stopsParams = (CGFloat*)malloc(stops.count * sizeof(CGFloat));
|
||||
|
||||
NSInteger i = 0;
|
||||
for(IJSVGNode* stopNode in stops) {
|
||||
NSColor* color = stopNode.fillColor;
|
||||
NSColor* color = ((IJSVGColorNode*)(stopNode.fill)).color;
|
||||
CGFloat opacity = stopNode.fillOpacity.value;
|
||||
CGFloat offset = stopNode.offset.value;
|
||||
stopsParams[i++] = offset;
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
// actually create the gradient
|
||||
NSInteger num = self.gradient.numberOfColorStops;
|
||||
CGFloat* locations = malloc(sizeof(CGFloat) * num);
|
||||
CGFloat* locations = (CGFloat*)malloc(sizeof(CGFloat) * num);
|
||||
CFMutableArrayRef colors = CFArrayCreateMutable(kCFAllocatorDefault, (CFIndex)num,
|
||||
&kCFTypeArrayCallBacks);
|
||||
for (NSInteger i = 0; i < num; i++) {
|
||||
@@ -113,7 +113,7 @@
|
||||
}
|
||||
CFArrayAppendValue(colors, color.CGColor);
|
||||
}
|
||||
CGGradientRef result = CGGradientCreateWithColors(self.gradient.colorSpace.CGColorSpace,
|
||||
CGGradientRef result = CGGradientCreateWithColors(_gradient.colorSpace.CGColorSpace,
|
||||
colors, locations);
|
||||
CFRelease(colors);
|
||||
free(locations);
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
@interface IJSVGGroup : IJSVGNode {
|
||||
|
||||
@private
|
||||
NSMutableArray<IJSVGNode*>* _childNodes;
|
||||
NSMutableArray<IJSVGNode*>* _children;
|
||||
}
|
||||
|
||||
@property (nonatomic, readonly) NSArray<IJSVGNode*>* children;
|
||||
|
||||
- (void)addChild:(IJSVGNode*)child;
|
||||
- (NSArray<IJSVGNode*>*)childNodes;
|
||||
- (void)purgeChildren;
|
||||
|
||||
@end
|
||||
|
||||
@@ -12,24 +12,24 @@
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_childNodes release]), _childNodes = nil;
|
||||
(void)([_children release]), _children = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
_childNodes = [[NSMutableArray alloc] init];
|
||||
_children = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)prepareFromCopy
|
||||
{
|
||||
if(_childNodes != nil) {
|
||||
(void)[_childNodes release], _childNodes = nil;
|
||||
if(_children != nil) {
|
||||
(void)[_children release], _children = nil;
|
||||
}
|
||||
_childNodes = [[NSMutableArray alloc] init];
|
||||
_children = [[NSMutableArray alloc] init];
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
@@ -37,7 +37,7 @@
|
||||
IJSVGGroup* node = [super copyWithZone:zone];
|
||||
[node prepareFromCopy];
|
||||
|
||||
for (IJSVGNode* childNode in _childNodes) {
|
||||
for (IJSVGNode* childNode in _children) {
|
||||
childNode = [[childNode copy] autorelease];
|
||||
childNode.parentNode = node;
|
||||
[node addChild:childNode];
|
||||
@@ -45,27 +45,41 @@
|
||||
return node;
|
||||
}
|
||||
|
||||
- (void)purgeChildren
|
||||
{
|
||||
[_childNodes removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)addChild:(IJSVGNode*)child
|
||||
{
|
||||
if (child != nil) {
|
||||
[_childNodes addObject:child];
|
||||
if(child == nil || (child.parentNode == self && [_children containsObject:child])) {
|
||||
return;
|
||||
}
|
||||
child.parentNode = self;
|
||||
[_children addObject:child];
|
||||
}
|
||||
|
||||
- (NSArray<IJSVGNode*>*)childNodes
|
||||
- (void)removeChild:(IJSVGNode*)child
|
||||
{
|
||||
return _childNodes;
|
||||
if(child.parentNode == self) {
|
||||
[child detach];
|
||||
}
|
||||
[_children removeObject:child];
|
||||
}
|
||||
|
||||
- (CGRect)bounds
|
||||
{
|
||||
CGRect rect = CGRectZero;
|
||||
for(IJSVGNode* node in self.children) {
|
||||
rect = CGRectUnion(rect, node.bounds);
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (NSArray<IJSVGNode*>*)children
|
||||
{
|
||||
return _children;
|
||||
}
|
||||
|
||||
- (NSString*)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ - %@",
|
||||
[super description], self.childNodes];
|
||||
[super description], self.children];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -12,15 +12,15 @@
|
||||
@class IJSVGPath;
|
||||
|
||||
@interface IJSVGImage : IJSVGNode {
|
||||
|
||||
NSImage* image;
|
||||
CGImageRef CGImage;
|
||||
IJSVGPath* imagePath;
|
||||
}
|
||||
|
||||
@property (nonatomic, readonly) CGSize intrinsicSize;
|
||||
@property (nonatomic, readonly) CGRect intrinsicBounds;
|
||||
@property (nonatomic, readonly) CGAffineTransform intrinsicTransform;
|
||||
@property (nonatomic, retain) NSImage* image;
|
||||
|
||||
- (CGImageRef)CGImage;
|
||||
- (void)drawInContextRef:(CGContextRef)context
|
||||
path:(IJSVGPath*)path;
|
||||
- (void)loadFromString:(NSString*)encodedString;
|
||||
- (void)loadFromURL:(NSURL*)aURL;
|
||||
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)(CGImageRelease(CGImage)), CGImage = nil;
|
||||
(void)([imagePath release]), imagePath = nil;
|
||||
(void)([image release]), image = nil;
|
||||
(void)([_image release]), _image = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -48,36 +47,24 @@
|
||||
[self setImage:anImage];
|
||||
}
|
||||
|
||||
- (IJSVGPath*)path
|
||||
{
|
||||
if (imagePath == nil) {
|
||||
// lazy load the path as it might not be needed
|
||||
imagePath = [[IJSVGPath alloc] init];
|
||||
CGRect rect = CGRectMake(0.f, 0.f, self.width.value, self.height.value);
|
||||
CGPathAddRect(imagePath.path, NULL, rect);
|
||||
[imagePath close];
|
||||
}
|
||||
return imagePath;
|
||||
}
|
||||
|
||||
- (void)setImage:(NSImage*)anImage
|
||||
{
|
||||
if (image != nil) {
|
||||
(void)([image release]), image = nil;
|
||||
if (_image != nil) {
|
||||
(void)([_image release]), _image = nil;
|
||||
}
|
||||
image = [anImage retain];
|
||||
_image = [anImage retain];
|
||||
_intrinsicSize = (CGSize)_image.size;
|
||||
|
||||
if (CGImage != nil) {
|
||||
CGImageRelease(CGImage);
|
||||
CGImage = nil;
|
||||
}
|
||||
|
||||
NSRect rect = NSMakeRect(0.f, 0.f, self.width.value, self.height.value);
|
||||
CGImage = [image CGImageForProposedRect:&rect
|
||||
context:nil
|
||||
hints:nil];
|
||||
NSRect rect = NSMakeRect(0.f, 0.f, _intrinsicSize.width, _intrinsicSize.height);
|
||||
CGImage = [_image CGImageForProposedRect:&rect
|
||||
context:nil
|
||||
hints:nil];
|
||||
|
||||
// be sure to retain (some reason this is required in Xcode 8 beta 5?)
|
||||
CGImageRetain(CGImage);
|
||||
}
|
||||
|
||||
@@ -86,32 +73,26 @@
|
||||
return CGImage;
|
||||
}
|
||||
|
||||
- (void)drawInContextRef:(CGContextRef)context
|
||||
path:(IJSVGPath*)path
|
||||
- (CGRect)intrinsicBounds
|
||||
{
|
||||
// run the transforms
|
||||
// draw the image
|
||||
if (self.width.value == 0.f || self.height.value == 0.f) {
|
||||
return;
|
||||
}
|
||||
CGRect rect = CGRectZero;
|
||||
rect.size.width = _intrinsicSize.width;
|
||||
rect.size.height = _intrinsicSize.height;
|
||||
return rect;
|
||||
}
|
||||
|
||||
// make sure path is set
|
||||
if (path == nil) {
|
||||
path = [self path];
|
||||
}
|
||||
- (CGAffineTransform)intrinsicTransform
|
||||
{
|
||||
CGFloat widthRatio = self.width.value / _intrinsicSize.width;
|
||||
CGFloat heightRatio = self.height.value / _intrinsicSize.height;
|
||||
return CGAffineTransformMakeScale(widthRatio, heightRatio);
|
||||
}
|
||||
|
||||
CGRect rect = path.pathBoundingBox;
|
||||
CGRect bounds = CGRectMake(0.f, 0.f, rect.size.width, rect.size.height);
|
||||
|
||||
// save the state of the context
|
||||
CGContextSaveGState(context);
|
||||
{
|
||||
// flip the coordinates
|
||||
CGContextTranslateCTM(context, rect.origin.x, (rect.origin.y) + rect.size.height);
|
||||
CGContextScaleCTM(context, 1.f, -1.f);
|
||||
CGContextDrawImage(context, bounds, CGImage);
|
||||
}
|
||||
CGContextRestoreGState(context);
|
||||
- (CGRect)bounds
|
||||
{
|
||||
return CGRectMake(0.f, 0.f,
|
||||
self.width.value,
|
||||
self.height.value);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
aGradient.x2 = [IJSVGGradientUnitLength unitWithString:x2 fromUnitType:aGradient.units];
|
||||
aGradient.y1 = [IJSVGGradientUnitLength unitWithString:y1 fromUnitType:aGradient.units];
|
||||
aGradient.y2 = [IJSVGGradientUnitLength unitWithString:y2 fromUnitType:aGradient.units];
|
||||
|
||||
|
||||
// compute the color stops and colours
|
||||
NSArray* colors = nil;
|
||||
CGFloat* stopsParams = [self.class computeColorStops:aGradient
|
||||
colors:&colors];
|
||||
|
||||
|
||||
// create the gradient with the colours
|
||||
NSGradient* grad = [[NSGradient alloc] initWithColors:colors
|
||||
atLocations:stopsParams
|
||||
@@ -51,7 +51,7 @@
|
||||
CGAffineTransform selfTransform = IJSVGConcatTransforms(self.transforms);
|
||||
|
||||
CGRect boundingBox = inUserSpace ? viewBox : objectRect;
|
||||
|
||||
|
||||
// make sure we apply the absolute position to
|
||||
// transform us back into the correct space
|
||||
if (inUserSpace == YES) {
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
gradientEndPoint = CGPointMake([self.x2 computeValue:width],
|
||||
[self.y2 computeValue:height]);
|
||||
|
||||
|
||||
// transform the context
|
||||
CGContextConcatCTM(ctx, selfTransform);
|
||||
|
||||
|
||||
@@ -8,20 +8,28 @@
|
||||
|
||||
#import <IJSVG/IJSVGStyle.h>
|
||||
#import <IJSVG/IJSVGUnitLength.h>
|
||||
#import <IJSVG/IJSVGViewBox.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class IJSVGNode;
|
||||
@class IJSVG;
|
||||
@class IJSVGGroup;
|
||||
@class IJSVGDef;
|
||||
@class IJSVGGradient;
|
||||
@class IJSVGGroup;
|
||||
@class IJSVGPattern;
|
||||
@class IJSVGTransform;
|
||||
@class IJSVGRootNode;
|
||||
@class IJSVGUnitRect;
|
||||
|
||||
typedef void (^IJSVGNodeWalkHandler)(IJSVGNode* node, BOOL* allowChildNodes, BOOL* stop);
|
||||
|
||||
typedef NS_OPTIONS(NSInteger, IJSVGNodeTraits) {
|
||||
IJSVGNodeTraitNone = 0,
|
||||
IJSVGNodeTraitStroked = 1 << 0,
|
||||
IJSVGNodeTraitPaintable = 1 << 1
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, IJSVGNodeType) {
|
||||
IJSVGNodeTypeGroup,
|
||||
IJSVGNodeTypePath,
|
||||
@@ -50,6 +58,7 @@ typedef NS_ENUM(NSInteger, IJSVGNodeType) {
|
||||
IJSVGNodeTypeDesc,
|
||||
IJSVGNodeTypeStop,
|
||||
IJSVGNodeTypeNotFound,
|
||||
IJSVGNodeTypeUnknown,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, IJSVGWindingRule) {
|
||||
@@ -108,6 +117,13 @@ static CGFloat IJSVGInheritedFloatValue = -99.9999991;
|
||||
|
||||
@interface IJSVGNode : NSObject <NSCopying>
|
||||
|
||||
void IJSVGAssertPaintableObject(id object);
|
||||
|
||||
@property (nonatomic, assign) IJSVGNodeTraits traits;
|
||||
@property (nonatomic, assign, readonly) CGRect bounds;
|
||||
@property (nonatomic, retain) IJSVGUnitRect* viewBox;
|
||||
@property (nonatomic, assign) IJSVGViewBoxAlignment viewBoxAlignment;
|
||||
@property (nonatomic, assign) IJSVGViewBoxMeetOrSlice viewBoxMeetOrSlice;
|
||||
@property (nonatomic, copy) NSString* title;
|
||||
@property (nonatomic, copy) NSString* desc;
|
||||
@property (nonatomic, assign) IJSVGNodeType type;
|
||||
@@ -116,7 +132,6 @@ static CGFloat IJSVGInheritedFloatValue = -99.9999991;
|
||||
@property (nonatomic, retain) NSArray* classNameList;
|
||||
@property (nonatomic, copy) NSString* unicode;
|
||||
@property (nonatomic, assign) BOOL shouldRender;
|
||||
@property (nonatomic, assign) BOOL usesDefaultFillColor;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* x;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* y;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* width;
|
||||
@@ -126,24 +141,19 @@ static CGFloat IJSVGInheritedFloatValue = -99.9999991;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* strokeOpacity;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* strokeWidth;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* offset;
|
||||
@property (nonatomic, retain) NSColor* fillColor;
|
||||
@property (nonatomic, retain) NSColor* strokeColor;
|
||||
@property (nonatomic, retain) IJSVGNode* fill;
|
||||
@property (nonatomic, retain) IJSVGNode* stroke;
|
||||
@property (nonatomic, copy) NSString* identifier;
|
||||
@property (nonatomic, assign) IJSVGNode* parentNode;
|
||||
@property (nonatomic, assign) IJSVGNode* intermediateParentNode;
|
||||
@property (nonatomic, retain) IJSVGGroup* clipPath;
|
||||
@property (nonatomic, retain) IJSVGGroup* mask;
|
||||
@property (nonatomic, assign) IJSVGWindingRule windingRule;
|
||||
@property (nonatomic, assign) IJSVGLineCapStyle lineCapStyle;
|
||||
@property (nonatomic, assign) IJSVGLineJoinStyle lineJoinStyle;
|
||||
@property (nonatomic, retain) NSArray<IJSVGTransform*>* transforms;
|
||||
@property (nonatomic, retain) IJSVGDef* def;
|
||||
@property (nonatomic, retain) IJSVGGradient* fillGradient;
|
||||
@property (nonatomic, retain) IJSVGPattern* fillPattern;
|
||||
@property (nonatomic, retain) IJSVGGradient* strokeGradient;
|
||||
@property (nonatomic, retain) IJSVGPattern* strokePattern;
|
||||
@property (nonatomic, assign) CGFloat* strokeDashArray;
|
||||
@property (nonatomic, assign) NSInteger strokeDashArrayCount;
|
||||
@property (nonatomic, readonly) NSArray<NSNumber*>* lineDashPattern;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* strokeDashOffset;
|
||||
@property (nonatomic, retain) IJSVG* svg;
|
||||
@property (nonatomic, assign) IJSVGUnitType contentUnits;
|
||||
@@ -158,8 +168,15 @@ static CGFloat IJSVGInheritedFloatValue = -99.9999991;
|
||||
kind:(NSXMLNodeKind)kind;
|
||||
|
||||
- (void)applyPropertiesFromNode:(IJSVGNode*)node;
|
||||
- (id)initWithDef:(BOOL)flag;
|
||||
- (void)addDef:(IJSVGNode*)aDef;
|
||||
- (IJSVGDef*)defForID:(NSString*)anID;
|
||||
|
||||
- (IJSVGUnitType)contentUnitsWithReferencingNodeBounds:(CGRect*)bounds;
|
||||
- (IJSVGUnitType)contentUnitsWithReferencingNode:(IJSVGNode**)referencingNode;
|
||||
|
||||
- (instancetype)detach;
|
||||
|
||||
- (void)addTraits:(IJSVGNodeTraits)traits;
|
||||
- (void)removeTraits:(IJSVGNodeTraits)traits;
|
||||
- (BOOL)matchesTraits:(IJSVGNodeTraits)traits;
|
||||
- (void)computeTraits;
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,13 +6,16 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGDef.h"
|
||||
#import "IJSVGNode.h"
|
||||
#import "IJSVGUtils.h"
|
||||
#import "IJSVGGroup.h"
|
||||
#import <IJSVG/IJSVGDef.h>
|
||||
#import <IJSVG/IJSVGNode.h>
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
|
||||
@implementation IJSVGNode
|
||||
|
||||
@synthesize fill = _fill;
|
||||
@synthesize stroke = _stroke;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)free(_strokeDashArray), _strokeDashArray = NULL;
|
||||
@@ -27,23 +30,19 @@
|
||||
(void)([_strokeWidth release]), _strokeWidth = nil;
|
||||
(void)([_strokeDashOffset release]), _strokeDashOffset = nil;
|
||||
(void)([_unicode release]), _unicode = nil;
|
||||
(void)([_fillGradient release]), _fillGradient = nil;
|
||||
(void)([_strokeGradient release]), _strokeGradient = nil;
|
||||
(void)([_strokePattern release]), _strokePattern = nil;
|
||||
(void)([_fill release]), _fill = nil;
|
||||
(void)([_stroke release]), _stroke = nil;
|
||||
(void)([_transforms release]), _transforms = nil;
|
||||
(void)([_fillColor release]), _fillColor = nil;
|
||||
(void)([_strokeColor release]), _strokeColor = nil;
|
||||
(void)([_identifier release]), _identifier = nil;
|
||||
(void)([_def release]), _def = nil;
|
||||
(void)([_name release]), _name = nil;
|
||||
(void)([_title release]), _title = nil;
|
||||
(void)([_desc release]), _desc = nil;
|
||||
(void)([_className release]), _className = nil;
|
||||
(void)([_classNameList release]), _classNameList = nil;
|
||||
(void)([_fillPattern release]), _fillPattern = nil;
|
||||
(void)([_clipPath release]), _clipPath = nil;
|
||||
(void)([_svg release]), _svg = nil;
|
||||
(void)([_mask release]), _mask = nil;
|
||||
(void)([_viewBox release]), _viewBox = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -137,15 +136,7 @@
|
||||
if(strcmp(name, "desc") == 0) {
|
||||
return IJSVGNodeTypeDesc;
|
||||
}
|
||||
return IJSVGNodeTypeNotFound;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [self initWithDef:YES]) != nil) {
|
||||
self.opacity = [IJSVGUnitLength unitWithFloat:1];
|
||||
}
|
||||
return self;
|
||||
return IJSVGNodeTypeUnknown;
|
||||
}
|
||||
|
||||
+ (void)walkNodeTree:(IJSVGNode*)node
|
||||
@@ -181,7 +172,7 @@
|
||||
|
||||
// iterate over the childnodes
|
||||
IJSVGGroup* group = (IJSVGGroup*)node;
|
||||
for(IJSVGNode* childNode in group.childNodes) {
|
||||
for(IJSVGNode* childNode in group.children) {
|
||||
[self _walkNodeTree:childNode
|
||||
handler:handler
|
||||
allowChildNodes:allowChildNodes
|
||||
@@ -192,6 +183,35 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
self.opacity = [IJSVGUnitLength unitWithFloat:1.f];
|
||||
self.fillOpacity = [IJSVGUnitLength unitWithFloat:1.f];
|
||||
self.fillOpacity.inherit = YES;
|
||||
|
||||
self.strokeDashOffset = [IJSVGUnitLength unitWithFloat:0.f];
|
||||
self.shouldRender = YES;
|
||||
|
||||
self.strokeOpacity = [IJSVGUnitLength unitWithFloat:1.f];
|
||||
self.strokeOpacity.inherit = YES;
|
||||
|
||||
self.strokeWidth = [IJSVGUnitLength unitWithFloat:1.f];
|
||||
self.strokeWidth.inherit = YES;
|
||||
|
||||
self.windingRule = IJSVGWindingRuleInherit;
|
||||
self.lineCapStyle = IJSVGLineCapStyleInherit;
|
||||
self.lineJoinStyle = IJSVGLineJoinStyleInherit;
|
||||
self.units = IJSVGUnitInherit;
|
||||
self.contentUnits = IJSVGUnitInherit;
|
||||
|
||||
self.blendMode = IJSVGBlendModeNormal;
|
||||
self.overflowVisibility = IJSVGOverflowVisibilityVisible;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)applyPropertiesFromNode:(IJSVGNode*)node
|
||||
{
|
||||
self.title = node.title;
|
||||
@@ -202,19 +222,18 @@
|
||||
self.unicode = node.unicode;
|
||||
self.className = node.className;
|
||||
self.classNameList = node.classNameList;
|
||||
|
||||
self.viewBox = node.viewBox;
|
||||
self.viewBoxAlignment = node.viewBoxAlignment;
|
||||
self.viewBoxMeetOrSlice = node.viewBoxMeetOrSlice;
|
||||
|
||||
self.x = node.x;
|
||||
self.y = node.y;
|
||||
self.width = node.width;
|
||||
self.height = node.height;
|
||||
|
||||
self.fillGradient = node.fillGradient;
|
||||
self.fillPattern = node.fillPattern;
|
||||
self.strokeGradient = node.strokeGradient;
|
||||
self.strokePattern = node.strokePattern;
|
||||
|
||||
self.fillColor = node.fillColor;
|
||||
self.strokeColor = node.strokeColor;
|
||||
self.fill = node.fill;
|
||||
self.stroke = node.stroke;
|
||||
self.clipPath = node.clipPath;
|
||||
|
||||
self.units = node.units;
|
||||
@@ -226,10 +245,8 @@
|
||||
self.strokeOpacity = node.strokeOpacity;
|
||||
|
||||
self.identifier = node.identifier;
|
||||
self.usesDefaultFillColor = node.usesDefaultFillColor;
|
||||
|
||||
self.transforms = node.transforms;
|
||||
self.def = node.def;
|
||||
self.windingRule = node.windingRule;
|
||||
self.lineCapStyle = node.lineCapStyle;
|
||||
self.lineJoinStyle = node.lineJoinStyle;
|
||||
@@ -254,52 +271,18 @@
|
||||
return node;
|
||||
}
|
||||
|
||||
- (id)initWithDef:(BOOL)flag
|
||||
- (void)setFill:(IJSVGNode*)fill
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
self.opacity = [IJSVGUnitLength unitWithFloat:0.f];
|
||||
self.fillOpacity = [IJSVGUnitLength unitWithFloat:1.f];
|
||||
self.fillOpacity.inherit = YES;
|
||||
|
||||
self.strokeDashOffset = [IJSVGUnitLength unitWithFloat:0.f];
|
||||
self.shouldRender = YES;
|
||||
|
||||
self.strokeOpacity = [IJSVGUnitLength unitWithFloat:1.f];
|
||||
self.strokeOpacity.inherit = YES;
|
||||
|
||||
self.strokeWidth = [IJSVGUnitLength unitWithFloat:1.f];
|
||||
self.strokeWidth.inherit = YES;
|
||||
|
||||
self.windingRule = IJSVGWindingRuleInherit;
|
||||
self.lineCapStyle = IJSVGLineCapStyleInherit;
|
||||
self.lineJoinStyle = IJSVGLineJoinStyleInherit;
|
||||
self.units = IJSVGUnitInherit;
|
||||
|
||||
self.blendMode = IJSVGBlendModeNormal;
|
||||
self.overflowVisibility = IJSVGOverflowVisibilityVisible;
|
||||
|
||||
if (flag == YES) {
|
||||
_def = [[IJSVGDef alloc] init];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
NSAssert([fill matchesTraits:IJSVGNodeTraitPaintable] || fill == nil, @"Fill must a paintable node.");
|
||||
(void)[_fill release], _fill = nil;
|
||||
_fill = [fill retain];
|
||||
}
|
||||
|
||||
- (IJSVGDef*)defForID:(NSString*)anID
|
||||
- (void)setStroke:(IJSVGNode*)stroke
|
||||
{
|
||||
IJSVGDef* aDef = nil;
|
||||
if ((aDef = [_def defForID:anID]) != nil) {
|
||||
return aDef;
|
||||
}
|
||||
if (_parentNode != nil) {
|
||||
return [_parentNode defForID:anID];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)addDef:(IJSVGNode*)aDef
|
||||
{
|
||||
[_def addDef:aDef];
|
||||
NSAssert([stroke matchesTraits:IJSVGNodeTraitPaintable]|| stroke == nil, @"Stroke must be a paintable node.");
|
||||
(void)[_stroke release], _stroke = nil;
|
||||
_stroke = [stroke retain];
|
||||
}
|
||||
|
||||
// winding rule can inherit..
|
||||
@@ -361,15 +344,23 @@
|
||||
return _strokeWidth;
|
||||
}
|
||||
|
||||
- (NSArray<NSNumber*>*)lineDashPattern
|
||||
{
|
||||
NSMutableArray* arr = [[[NSMutableArray alloc] initWithCapacity:self.strokeDashArrayCount] autorelease];
|
||||
for (NSInteger i = 0; i < self.strokeDashArrayCount; i++) {
|
||||
[arr addObject:@((CGFloat)self.strokeDashArray[i])];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
// these are all recursive, so go up the chain
|
||||
// if they dont exist on this specific node
|
||||
- (NSColor*)strokeColor
|
||||
- (IJSVGNode*)stroke
|
||||
{
|
||||
if (_strokeColor != nil)
|
||||
return _strokeColor;
|
||||
if (_strokeColor == nil && _parentNode != nil)
|
||||
return _parentNode.strokeColor;
|
||||
return nil;
|
||||
if (_stroke == nil && _parentNode != nil) {
|
||||
return _parentNode.stroke;
|
||||
}
|
||||
return _stroke;
|
||||
}
|
||||
|
||||
- (IJSVGUnitLength*)strokeOpacity
|
||||
@@ -382,52 +373,76 @@
|
||||
|
||||
// even though the spec explicity states fill color
|
||||
// must be on the path, it can also be on the
|
||||
- (NSColor*)fillColor
|
||||
- (IJSVGNode*)fill
|
||||
{
|
||||
if (_fillColor == nil && _parentNode != nil) {
|
||||
return _parentNode.fillColor;
|
||||
if (_fill == nil && _parentNode != nil) {
|
||||
return _parentNode.fill;
|
||||
}
|
||||
return _fillColor;
|
||||
return _fill;
|
||||
}
|
||||
|
||||
// these are all recursive, so go up the chain
|
||||
// if they dont exist on this specific node
|
||||
- (IJSVGGradient*)fillGradient
|
||||
- (IJSVGUnitType)units
|
||||
{
|
||||
if (_fillGradient == nil && _parentNode != nil) {
|
||||
return _parentNode.fillGradient;
|
||||
if(_units == IJSVGUnitInherit && _parentNode != nil) {
|
||||
return _parentNode.units;
|
||||
}
|
||||
return _fillGradient;
|
||||
return _units;
|
||||
}
|
||||
|
||||
// these are all recursive, so go up the chain
|
||||
// if they dont exist on this specific node
|
||||
- (IJSVGPattern*)fillPattern
|
||||
- (IJSVGUnitType)contentUnits
|
||||
{
|
||||
if (_fillPattern == nil && _parentNode != nil) {
|
||||
return _parentNode.fillPattern;
|
||||
if(_contentUnits == IJSVGUnitInherit && _parentNode != nil) {
|
||||
return _parentNode.contentUnits;
|
||||
}
|
||||
return _fillPattern;
|
||||
return _contentUnits;
|
||||
}
|
||||
|
||||
// these are all recursive, so go up the chain
|
||||
// if they dont exist on this specific node
|
||||
- (IJSVGGradient*)strokeGradient
|
||||
- (IJSVGUnitType)contentUnitsWithReferencingNodeBounds:(CGRect*)bounds
|
||||
{
|
||||
if (_strokeGradient == nil && _parentNode != nil) {
|
||||
return _parentNode.strokeGradient;
|
||||
}
|
||||
return _strokeGradient;
|
||||
IJSVGNode* node = nil;
|
||||
IJSVGUnitType type = [self contentUnitsWithReferencingNode:&node];
|
||||
*bounds = node.parentNode.bounds;
|
||||
return type;
|
||||
}
|
||||
|
||||
// these are all recursive, so go up the chain
|
||||
// if they dont exist on this specific node
|
||||
- (IJSVGPattern*)strokePattern
|
||||
- (IJSVGUnitType)contentUnitsWithReferencingNode:(IJSVGNode**)referencingNode
|
||||
{
|
||||
if (_strokePattern == nil && _parentNode != nil) {
|
||||
return _parentNode.strokePattern;
|
||||
if(_contentUnits == IJSVGUnitInherit && _parentNode != nil) {
|
||||
return [_parentNode contentUnitsWithReferencingNode:referencingNode];
|
||||
}
|
||||
return _strokePattern;
|
||||
*referencingNode = self;
|
||||
return _contentUnits;
|
||||
}
|
||||
|
||||
- (void)addTraits:(IJSVGNodeTraits)traits
|
||||
{
|
||||
_traits |= traits;
|
||||
}
|
||||
|
||||
- (void)removeTraits:(IJSVGNodeTraits)traits
|
||||
{
|
||||
_traits = _traits & ~traits;
|
||||
}
|
||||
|
||||
- (BOOL)matchesTraits:(IJSVGNodeTraits)traits
|
||||
{
|
||||
return (_traits & traits) == traits;
|
||||
}
|
||||
|
||||
- (void)computeTraits
|
||||
{
|
||||
// by default this does nothing
|
||||
}
|
||||
|
||||
- (instancetype)detach
|
||||
{
|
||||
self.parentNode = nil;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ %@ %@",self.name,self.classNameList,self.identifier];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGNode.h>
|
||||
#import <IJSVG/IJSVGColorNode.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class IJSVGGroup;
|
||||
@@ -29,7 +30,6 @@ typedef NS_ENUM(NSInteger, IJSVGPrimitivePathType) {
|
||||
@property (nonatomic, assign) CGPoint lastControlPoint;
|
||||
@property (nonatomic, readonly) CGRect controlPointBoundingBox;
|
||||
@property (nonatomic, readonly) CGRect pathBoundingBox;
|
||||
@property (nonatomic, assign, readonly) BOOL isStroked;
|
||||
|
||||
- (void)close;
|
||||
- (NSPoint)currentPoint;
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGGroup.h"
|
||||
#import "IJSVGPath.h"
|
||||
#import <IJSVG/IJSVGPath.h>
|
||||
|
||||
@implementation IJSVGPath
|
||||
|
||||
@@ -28,6 +27,11 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGRect)bounds
|
||||
{
|
||||
return self.pathBoundingBox;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
IJSVGPath* node = [super copyWithZone:zone];
|
||||
@@ -65,11 +69,23 @@
|
||||
CGPathCloseSubpath(_path);
|
||||
}
|
||||
|
||||
- (BOOL)isStroked
|
||||
#pragma mark Traits
|
||||
|
||||
- (void)computeTraits
|
||||
{
|
||||
return (self.strokeColor != nil && self.strokeColor.alphaComponent != 0.f) ||
|
||||
self.strokePattern != nil ||
|
||||
self.strokeGradient != nil;
|
||||
if(self.stroke != nil) {
|
||||
// by default we can just add this on
|
||||
[self addTraits:IJSVGNodeTraitStroked];
|
||||
|
||||
// if we detect the stroke was a color, we need to check its alpha
|
||||
// component to then remove the trait if its 0.f
|
||||
if([self.stroke isKindOfClass:IJSVGColorNode.class] == YES) {
|
||||
IJSVGColorNode* strokeColor = (IJSVGColorNode*)self.stroke;
|
||||
if(strokeColor.color.alphaComponent == 0.f) {
|
||||
[self removeTraits:IJSVGNodeTraitStroked];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
// Copyright © 2016 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
#import <IJSVG/IJSVGImage.h>
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGPattern : IJSVGGroup {
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,7 +7,19 @@
|
||||
//
|
||||
|
||||
#import "IJSVGPattern.h"
|
||||
#import "IJSVGUnitRect.h"
|
||||
|
||||
@implementation IJSVGPattern
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if((self = [super init]) != nil) {
|
||||
self.viewBox = nil;
|
||||
self.viewBoxAlignment = IJSVGViewBoxAlignmentXMidYMid;
|
||||
self.viewBoxMeetOrSlice = IJSVGViewBoxMeetOrSliceMeet;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
@property (nonatomic, retain) IJSVGUnitLength* cy;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* fx;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* fy;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* radius;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* fr;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* r;
|
||||
|
||||
+ (NSGradient*)parseGradient:(NSXMLElement*)element
|
||||
gradient:(IJSVGRadialGradient*)gradient;
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGRadialGradient.h"
|
||||
#import "IJSVGParser.h"
|
||||
#import <IJSVG/IJSVGRadialGradient.h>
|
||||
#import <IJSVG/IJSVGParser.h>
|
||||
|
||||
@implementation IJSVGRadialGradient
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
(void)([_cy release]), _cy = nil;
|
||||
(void)([_fx release]), _fx = nil;
|
||||
(void)([_fy release]), _fy = nil;
|
||||
(void)([_radius release]), _radius = nil;
|
||||
(void)([_fr release]), _fr = nil;
|
||||
(void)([_r release]), _r = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -26,9 +27,10 @@
|
||||
IJSVGRadialGradient* grad = [super copyWithZone:zone];
|
||||
grad.fx = _fx;
|
||||
grad.fy = _fy;
|
||||
grad.fr = _fr;
|
||||
grad.cx = _cx;
|
||||
grad.cy = _cy;
|
||||
grad.radius = _radius;
|
||||
grad.r = _r;
|
||||
return grad;
|
||||
}
|
||||
|
||||
@@ -39,7 +41,7 @@
|
||||
NSDictionary* kv = @{
|
||||
IJSVGAttributeCX : @"cx",
|
||||
IJSVGAttributeCY : @"cy",
|
||||
IJSVGAttributeR : @"radius" };
|
||||
IJSVGAttributeR : @"r" };
|
||||
|
||||
for (NSString* key in kv.allKeys) {
|
||||
NSString* str = [element attributeForName:key].stringValue;
|
||||
@@ -54,6 +56,15 @@
|
||||
[gradient setValue:unit
|
||||
forKey:kv[key]];
|
||||
}
|
||||
|
||||
// fr
|
||||
NSString* fr = [element attributeForName:IJSVGAttributeFR].stringValue;
|
||||
if(fr != nil) {
|
||||
gradient.fr = [IJSVGUnitLength unitWithString:fr
|
||||
fromUnitType:gradient.units];
|
||||
} else {
|
||||
gradient.fr = [IJSVGUnitLength unitWithPercentageFloat:0.f];
|
||||
}
|
||||
|
||||
// fx and fy are the same unless specified otherwise
|
||||
gradient.fx = gradient.cx;
|
||||
@@ -67,7 +78,7 @@
|
||||
}
|
||||
|
||||
NSString* fy = [element attributeForName:IJSVGAttributeFY].stringValue;
|
||||
if (fx != nil) {
|
||||
if (fy != nil) {
|
||||
gradient.fy = [IJSVGUnitLength unitWithString:fy
|
||||
fromUnitType:gradient.units];
|
||||
}
|
||||
@@ -92,6 +103,7 @@
|
||||
absoluteTransform:(CGAffineTransform)absoluteTransform
|
||||
viewPort:(CGRect)viewBox
|
||||
{
|
||||
CGContextSaveGState(ctx);
|
||||
BOOL inUserSpace = self.units == IJSVGUnitUserSpaceOnUse;
|
||||
CGFloat radius = 0.f;
|
||||
CGPoint startPoint = CGPointZero;
|
||||
@@ -102,56 +114,72 @@
|
||||
CGAffineTransform selfTransform = IJSVGConcatTransforms(self.transforms);
|
||||
|
||||
CGRect boundingBox = inUserSpace ? viewBox : objectRect;
|
||||
|
||||
// make sure we apply the absolute position to
|
||||
// transform us back into the correct space
|
||||
if (inUserSpace == YES) {
|
||||
CGContextConcatCTM(ctx, absoluteTransform);
|
||||
}
|
||||
|
||||
|
||||
// compute size based on percentages
|
||||
CGFloat x = [_cx computeValue:CGRectGetWidth(boundingBox)];
|
||||
CGFloat y = [_cy computeValue:CGRectGetHeight(boundingBox)];
|
||||
startPoint = CGPointMake(x, y);
|
||||
CGFloat val = MIN(CGRectGetWidth(boundingBox),
|
||||
CGRectGetHeight(boundingBox));
|
||||
radius = [_radius computeValue:val];
|
||||
CGFloat width = CGRectGetWidth(boundingBox);
|
||||
CGFloat height = CGRectGetHeight(boundingBox);
|
||||
CGFloat cx = [_cx computeValue:width];
|
||||
CGFloat cy = [_cy computeValue:height];
|
||||
startPoint = CGPointMake(cx, cy);
|
||||
CGFloat val = MIN(width, height);
|
||||
radius = [_r computeValue:val];
|
||||
CGFloat focalRadius = [_fr computeValue:val];
|
||||
|
||||
CGFloat ex = [_fx computeValue:CGRectGetWidth(boundingBox)];
|
||||
CGFloat ey = [_fy computeValue:CGRectGetHeight(boundingBox)];
|
||||
CGFloat fx = [_fx computeValue:width];
|
||||
CGFloat fy = [_fy computeValue:height];
|
||||
|
||||
gradientEndPoint = CGPointMake(ex, ey);
|
||||
gradientEndPoint = CGPointMake(fx, fy);
|
||||
gradientStartPoint = startPoint;
|
||||
|
||||
// transform if width or height is not equal - this can only
|
||||
// be done if we are using objectBoundingBox
|
||||
if (inUserSpace == NO && CGRectGetWidth(boundingBox) != CGRectGetHeight(boundingBox)) {
|
||||
CGAffineTransform tr = CGAffineTransformMakeTranslation(gradientStartPoint.x,
|
||||
gradientStartPoint.y);
|
||||
if (CGRectGetWidth(boundingBox) > CGRectGetHeight(boundingBox)) {
|
||||
tr = CGAffineTransformScale(tr, CGRectGetWidth(boundingBox) / CGRectGetHeight(boundingBox), 1);
|
||||
if(inUserSpace == YES) {
|
||||
CGFloat rad = 2.f * radius;
|
||||
CGRect rect = CGRectMake(startPoint.x, startPoint.y, rad, rad);
|
||||
rect = CGRectApplyAffineTransform(rect, selfTransform);
|
||||
rect = CGRectApplyAffineTransform(rect, absoluteTransform);
|
||||
radius = CGRectGetHeight(rect) / 2.f;
|
||||
CGContextConcatCTM(ctx, absoluteTransform);
|
||||
} else if(width != height) {
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
CGAffineTransform invert = CGAffineTransformIdentity;
|
||||
CGPoint invPoint = CGPointZero;
|
||||
CGFloat* radiusScale;
|
||||
if(width > height) {
|
||||
transform = CGAffineTransformMakeScale(1.f, height / width);
|
||||
radiusScale = &invPoint.y;
|
||||
} else {
|
||||
tr = CGAffineTransformScale(tr, 1.f, CGRectGetHeight(boundingBox) / CGRectGetWidth(boundingBox));
|
||||
transform = CGAffineTransformMakeScale(width / height, 1.f);
|
||||
radiusScale = &invPoint.x;
|
||||
}
|
||||
tr = CGAffineTransformTranslate(tr, -gradientStartPoint.x, -gradientStartPoint.y);
|
||||
selfTransform = CGAffineTransformConcat(tr, selfTransform);
|
||||
invert = CGAffineTransformInvert(transform);
|
||||
invPoint.x = invert.a;
|
||||
invPoint.y = invert.d;
|
||||
gradientStartPoint.x *= invPoint.x;
|
||||
gradientStartPoint.y *= invPoint.y;
|
||||
gradientEndPoint.x *= invPoint.x;
|
||||
gradientEndPoint.y *= invPoint.y;
|
||||
radius *= *radiusScale;
|
||||
focalRadius *= *radiusScale;
|
||||
selfTransform = CGAffineTransformConcat(transform, selfTransform);
|
||||
}
|
||||
|
||||
|
||||
// transform the context
|
||||
CGContextConcatCTM(ctx, selfTransform);
|
||||
|
||||
// draw the gradient
|
||||
CGGradientDrawingOptions options = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
|
||||
CGContextDrawRadialGradient(ctx, self.CGGradient,
|
||||
gradientEndPoint, 0,
|
||||
gradientEndPoint, focalRadius,
|
||||
gradientStartPoint,
|
||||
radius, options);
|
||||
CGContextRestoreGState(ctx);
|
||||
|
||||
#ifdef IJSVG_DEBUG_GRADIENTS
|
||||
[self _debugStart:gradientStartPoint
|
||||
end:gradientEndPoint
|
||||
context:ctx];
|
||||
#endif
|
||||
//#ifdef IJSVG_DEBUG_GRADIENTS
|
||||
// [self _debugStart:gradientStartPoint
|
||||
// end:gradientEndPoint
|
||||
// context:ctx];
|
||||
//#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// IJSVGRootNode.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 28/03/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVG.h>
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
#import <IJSVG/IJSVGUnitSize.h>
|
||||
|
||||
@interface IJSVGRootNode : IJSVGGroup
|
||||
|
||||
@property (nonatomic, retain) IJSVGUnitSize* intrinsicSize;
|
||||
@property (nonatomic, readonly) CGRect bounds;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// IJSVGRootNode.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 28/03/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGRootNode.h"
|
||||
|
||||
@implementation IJSVGRootNode
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)[_intrinsicSize release], _intrinsicSize = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if((self = [super init]) != nil) {
|
||||
self.viewBoxAlignment = IJSVGViewBoxAlignmentXMidYMid;
|
||||
self.viewBoxMeetOrSlice = IJSVGViewBoxMeetOrSliceMeet;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGRect)bounds
|
||||
{
|
||||
return [self.viewBox computeValue:CGSizeZero];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -12,6 +12,7 @@
|
||||
#import <IJSVG/IJSVGError.h>
|
||||
#import <IJSVG/IJSVGForeignObject.h>
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
#import <IJSVG/IJSVGColorNode.h>
|
||||
#import <IJSVG/IJSVGImage.h>
|
||||
#import <IJSVG/IJSVGLinearGradient.h>
|
||||
#import <IJSVG/IJSVGPath.h>
|
||||
@@ -26,6 +27,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
extern NSString* const IJSVGAttributeViewBox;
|
||||
extern NSString* const IJSVGAttributePreserveAspectRatio;
|
||||
extern NSString* const IJSVGAttributeID;
|
||||
extern NSString* const IJSVGAttributeClass;
|
||||
extern NSString* const IJSVGAttributeX;
|
||||
@@ -40,6 +42,7 @@ extern NSString* const IJSVGAttributeFillOpacity;
|
||||
extern NSString* const IJSVGAttributeClipPath;
|
||||
extern NSString* const IJSVGAttributeMask;
|
||||
extern NSString* const IJSVGAttributeGradientUnits;
|
||||
extern NSString* const IJSVGAttributePatternContentUnits;
|
||||
extern NSString* const IJSVGAttributeMaskUnits;
|
||||
extern NSString* const IJSVGAttributeMaskContentUnits;
|
||||
extern NSString* const IJSVGAttributeTransform;
|
||||
@@ -65,6 +68,7 @@ extern NSString* const IJSVGAttributeRY;
|
||||
extern NSString* const IJSVGAttributeCX;
|
||||
extern NSString* const IJSVGAttributeCY;
|
||||
extern NSString* const IJSVGAttributeR;
|
||||
extern NSString* const IJSVGAttributeFR;
|
||||
extern NSString* const IJSVGAttributeFX;
|
||||
extern NSString* const IJSVGAttributeFY;
|
||||
extern NSString* const IJSVGAttributePoints;
|
||||
@@ -80,39 +84,28 @@ extern NSString* const IJSVGAttributeOverflow;
|
||||
@protocol IJSVGParserDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
- (BOOL)svgParser:(IJSVGParser*)svg
|
||||
shouldHandleForeignObject:(IJSVGForeignObject*)foreignObject;
|
||||
- (void)svgParser:(IJSVGParser*)svg
|
||||
handleForeignObject:(IJSVGForeignObject*)foreignObject
|
||||
document:(NSXMLDocument*)document;
|
||||
- (void)svgParser:(IJSVGParser*)svg
|
||||
foundSubSVG:(IJSVG*)subSVG
|
||||
withSVGString:(NSString*)string;
|
||||
|
||||
@end
|
||||
|
||||
@interface IJSVGParser : IJSVGGroup {
|
||||
@interface IJSVGParser : NSObject {
|
||||
|
||||
@private
|
||||
id<IJSVGParserDelegate> _delegate;
|
||||
NSXMLDocument* _document;
|
||||
NSMutableArray<IJSVGPath*>* _glyphs;
|
||||
IJSVGStyleSheet* _styleSheet;
|
||||
NSMutableDictionary<NSString*, NSXMLElement*>* _defNodes;
|
||||
NSMutableDictionary<NSString*, NSXMLElement*>* _baseDefNodes;
|
||||
NSMutableArray<IJSVG*>* _svgs;
|
||||
|
||||
struct {
|
||||
unsigned int shouldHandleForeignObject : 1;
|
||||
unsigned int handleForeignObject : 1;
|
||||
unsigned int handleSubSVG : 1;
|
||||
} _respondsTo;
|
||||
|
||||
IJSVGPathDataStream* _commandDataStream;
|
||||
IJSVGStyleSheet* _styleSheet;
|
||||
NSMapTable<IJSVGNode*, NSMutableDictionary<NSString*, NSXMLElement*>*>* _detachedElements;
|
||||
}
|
||||
|
||||
@property (nonatomic, readonly) NSRect viewBox;
|
||||
@property (nonatomic, readonly) IJSVGUnitSize* intrinsicSize;
|
||||
@property (nonatomic, retain, readonly) IJSVGRootNode* rootNode;
|
||||
|
||||
+ (BOOL)isDataSVG:(NSData*)data;
|
||||
|
||||
@@ -129,9 +122,5 @@ extern NSString* const IJSVGAttributeOverflow;
|
||||
+ (IJSVGParser*)groupForFileURL:(NSURL*)aURL
|
||||
error:(NSError**)error
|
||||
delegate:(id<IJSVGParserDelegate>)delegate;
|
||||
- (NSSize)size;
|
||||
- (BOOL)isFont;
|
||||
- (NSArray*)glyphs;
|
||||
- (NSArray<IJSVG*>*)subSVGs:(BOOL)recursive;
|
||||
|
||||
@end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,13 +11,20 @@
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
@class IJSVGLayer;
|
||||
@class IJSVGRootLayer;
|
||||
@class IJSVGRootNode;
|
||||
|
||||
@interface IJSVGLayerTree : NSObject {
|
||||
@private
|
||||
NSMutableArray<NSValue*>* _viewPortStack;
|
||||
}
|
||||
|
||||
@property (nonatomic, assign) CGRect viewBox;
|
||||
@property (nonatomic, assign) CGFloat backingScale;
|
||||
@property (nonatomic, retain) IJSVGRenderingStyle* style;
|
||||
|
||||
- (IJSVGLayer*)layerForNode:(IJSVGNode*)node;
|
||||
- (id)initWithViewPortRect:(CGRect)viewPort
|
||||
backingScale:(CGFloat)scale;
|
||||
- (IJSVGRootLayer*)rootLayerForRootNode:(IJSVGRootNode*)rootNode;
|
||||
|
||||
@end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,11 +41,11 @@ IJSVGNode * IJSVGStyleSheetPreviousNode(IJSVGNode * node)
|
||||
IJSVGGroup * group = (IJSVGGroup *)node.parentNode;
|
||||
if([group isKindOfClass:[IJSVGGroup class]] == NO)
|
||||
return nil;
|
||||
NSInteger currentIndex = [group.childNodes indexOfObject:node];
|
||||
NSInteger currentIndex = [group.children indexOfObject:node];
|
||||
if(currentIndex == 0) {
|
||||
return nil;
|
||||
}
|
||||
return group.childNodes[currentIndex-1];
|
||||
return group.children[currentIndex-1];
|
||||
};
|
||||
|
||||
IJSVGNode * IJSVGStyleSheetNextNode(IJSVGNode * node)
|
||||
@@ -54,11 +54,11 @@ IJSVGNode * IJSVGStyleSheetNextNode(IJSVGNode * node)
|
||||
if([group isKindOfClass:[IJSVGGroup class]] == NO) {
|
||||
return nil;
|
||||
}
|
||||
NSInteger currentIndex = [group.childNodes indexOfObject:node];
|
||||
if(currentIndex == group.childNodes.count-1) {
|
||||
NSInteger currentIndex = [group.children indexOfObject:node];
|
||||
if(currentIndex == group.children.count-1) {
|
||||
return nil;
|
||||
}
|
||||
return group.childNodes[currentIndex+1];
|
||||
return group.children[currentIndex+1];
|
||||
};
|
||||
|
||||
IJSVGStyleSheetSelectorRaw * IJSVGStyleSheetPreviousSelector(IJSVGStyleSheetSelectorRaw * aSelector, NSArray * _rawSelectors)
|
||||
@@ -147,7 +147,7 @@ BOOL IJSVGStyleSheetMatchSelector(IJSVGNode * node, IJSVGStyleSheetSelectorRaw *
|
||||
}
|
||||
|
||||
// grab the children
|
||||
NSArray * nodes = parentNode.childNodes;
|
||||
NSArray * nodes = parentNode.children;
|
||||
NSInteger index = [nodes indexOfObject:aNode];
|
||||
|
||||
// doesnt contain the child
|
||||
@@ -226,7 +226,7 @@ BOOL IJSVGStyleSheetMatchSelector(IJSVGNode * node, IJSVGStyleSheetSelectorRaw *
|
||||
// matches the next selector and... contains the node in question
|
||||
IJSVGStyleSheetSelectorRaw * s = IJSVGStyleSheetNextSelector(aSelector,_rawSelectors);
|
||||
if(IJSVGStyleSheetMatchSelector(parentNode, s) &&
|
||||
[parentNode.childNodes containsObject:aNode]) {
|
||||
[parentNode.children containsObject:aNode]) {
|
||||
// set the new starting selector and node
|
||||
aSelector = s;
|
||||
aNode = parentNode;
|
||||
|
||||
@@ -15,7 +15,7 @@ typedef struct {
|
||||
|
||||
IJSVGParsingStringMethod* IJSVGParsingStringMethodCreate(void);
|
||||
void IJSVGParsingStringMethodRelease(IJSVGParsingStringMethod* stringMethod);
|
||||
IJSVGParsingStringMethod** IJSVGParsingMethodParseString(char* string,
|
||||
IJSVGParsingStringMethod** IJSVGParsingMethodParseString(const char* string,
|
||||
NSUInteger* count);
|
||||
void IJSVGParsingStringMethodsRelease(IJSVGParsingStringMethod** methods,
|
||||
NSUInteger count);
|
||||
|
||||
@@ -39,10 +39,10 @@ void IJSVGParsingStringMethodsRelease(IJSVGParsingStringMethod** methods,
|
||||
(void)free(methods), methods = NULL;
|
||||
}
|
||||
|
||||
IJSVGParsingStringMethod** IJSVGParsingMethodParseString(char* string,
|
||||
IJSVGParsingStringMethod** IJSVGParsingMethodParseString(const char* string,
|
||||
NSUInteger* count)
|
||||
{
|
||||
char* charString = string;
|
||||
const char* charString = string;
|
||||
unsigned long length = strlen(string);
|
||||
char* buffer = (char*)calloc(sizeof(char), length);
|
||||
char* originBuffer = buffer;
|
||||
|
||||
@@ -35,6 +35,7 @@ typedef NS_ENUM(NSInteger, IJSVGTransformCommand) {
|
||||
@property (nonatomic, assign) NSInteger sort;
|
||||
|
||||
void IJSVGApplyTransform(NSArray<IJSVGTransform*>* transforms, IJSVGTransformApplyBlock block);
|
||||
BOOL IJSVGAffineTransformScalesAndTranslates(CGAffineTransform affineTransform);
|
||||
CGAffineTransform IJSVGConcatTransforms(NSArray<IJSVGTransform*>* transforms);
|
||||
NSString* IJSVGTransformAttributeString(CGAffineTransform transform);
|
||||
|
||||
@@ -47,6 +48,8 @@ NSString* IJSVGTransformAttributeString(CGAffineTransform transform);
|
||||
+ (NSString*)affineTransformToSVGMatrixString:(CGAffineTransform)affineTransform;
|
||||
+ (NSString*)affineTransformToSVGMatrixString:(CGAffineTransform)transform
|
||||
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions;
|
||||
- (void)applyBounds:(CGRect)bounds
|
||||
withContentUnits:(IJSVGUnitType)contentUnits;
|
||||
- (CGAffineTransform)CGAffineTransform;
|
||||
- (CGAffineTransform)CGAffineTransformWithModifier:(IJSVGTransformParameterModifier)modifier;
|
||||
- (CGAffineTransform)stackIdentity:(CGAffineTransform)identity;
|
||||
|
||||
@@ -50,6 +50,16 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform*>* transforms, IJSVGTransformApp
|
||||
}
|
||||
};
|
||||
|
||||
BOOL IJSVGAffineTransformScalesAndTranslates(CGAffineTransform transform)
|
||||
{
|
||||
if(transform.tx != 0.f || transform.ty != 0.f) {
|
||||
CGFloat scaleX = sqrt(pow(transform.a, 2.f) + pow(transform.c, 2.f));
|
||||
CGFloat scaleY = sqrt(pow(transform.b, 2.f) + pow(transform.d, 2.f));
|
||||
return scaleX != 1.f || scaleY != 1.f;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (IJSVGTransform*)transformByTranslatingX:(CGFloat)x
|
||||
y:(CGFloat)y
|
||||
{
|
||||
@@ -171,9 +181,8 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform*>* transforms, IJSVGTransformApp
|
||||
const char* charString = string.UTF8String;
|
||||
IJSVGParsingStringMethod** methods = NULL;
|
||||
NSUInteger count = 0;
|
||||
methods = IJSVGParsingMethodParseString((char*)charString, &count);
|
||||
methods = IJSVGParsingMethodParseString(charString, &count);
|
||||
for(int i = 0; i < count; i++) {
|
||||
|
||||
IJSVGParsingStringMethod* method = methods[i];
|
||||
IJSVGTransformCommand commandType;
|
||||
commandType = [self.class commandForCommandCString:method->name];
|
||||
@@ -199,6 +208,26 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform*>* transforms, IJSVGTransformApp
|
||||
return transforms;
|
||||
}
|
||||
|
||||
- (void)applyBounds:(CGRect)bounds
|
||||
withContentUnits:(IJSVGUnitType)contentUnits
|
||||
{
|
||||
if(contentUnits != IJSVGUnitObjectBoundingBox) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(self.command) {
|
||||
case IJSVGTransformCommandTranslate: {
|
||||
self.parameters[0] *= bounds.size.width;
|
||||
if(self.parameterCount == 2) {
|
||||
self.parameters[1] *= bounds.size.height;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (CGAffineTransform)CGAffineTransform
|
||||
{
|
||||
return [self stackIdentity:CGAffineTransformIdentity];
|
||||
@@ -606,7 +635,7 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform*>* transforms, IJSVGTransformApp
|
||||
- (NSString*)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ %@", [super description],
|
||||
[self.class affineTransformToSVGMatrixString:self.CGAffineTransform]];
|
||||
[self.class affineTransformToSVGTransformComponentString:self.CGAffineTransform]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -30,13 +30,15 @@ typedef NS_ENUM(NSInteger, IJSVGUnitType) {
|
||||
IJSVGUnitInherit
|
||||
};
|
||||
|
||||
@interface IJSVGUnitLength : NSObject
|
||||
@interface IJSVGUnitLength : NSObject <NSCopying>
|
||||
|
||||
@property (nonatomic, assign) IJSVGUnitLengthType type;
|
||||
@property (nonatomic, assign) IJSVGUnitLengthType originalType;
|
||||
@property (nonatomic, assign) CGFloat value;
|
||||
@property (nonatomic, assign) BOOL inherit;
|
||||
|
||||
+ (IJSVGUnitLength*)zeroUnitLength;
|
||||
|
||||
+ (IJSVGUnitLength*)unitWithFloat:(CGFloat)number;
|
||||
+ (IJSVGUnitLength*)unitWithFloat:(CGFloat)number
|
||||
type:(IJSVGUnitLengthType)type;
|
||||
@@ -47,6 +49,8 @@ typedef NS_ENUM(NSInteger, IJSVGUnitType) {
|
||||
+ (IJSVGUnitLength*)unitWithString:(NSString*)string
|
||||
fromUnitType:(IJSVGUnitType)units;
|
||||
|
||||
- (IJSVGUnitLength*)lengthWithUnitType:(IJSVGUnitLengthType)type;
|
||||
- (IJSVGUnitLength*)lengthByMatchingPercentage;
|
||||
- (CGFloat)valueAsPercentage;
|
||||
- (CGFloat)computeValue:(CGFloat)anotherValue;
|
||||
- (NSString*)stringValue;
|
||||
|
||||
@@ -12,6 +12,12 @@
|
||||
|
||||
@implementation IJSVGUnitLength
|
||||
|
||||
+ (IJSVGUnitLength*)zeroUnitLength
|
||||
{
|
||||
return [self unitWithFloat:0.f
|
||||
type:IJSVGUnitLengthTypeNumber];
|
||||
}
|
||||
|
||||
+ (IJSVGUnitLength*)unitWithFloat:(CGFloat)number
|
||||
{
|
||||
IJSVGUnitLength* unit = [[[self alloc] init] autorelease];
|
||||
@@ -143,12 +149,12 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
const char* chars = string.UTF8String;
|
||||
IJSVGTrimCharBuffer((char*)chars);
|
||||
char* chars = IJSVGTimmedCharBufferCreate(string.UTF8String);
|
||||
|
||||
// is inherit or just nothing
|
||||
size_t strl = strlen(chars);
|
||||
if (strcmp(chars, "inherit") == 0 || strl == 0) {
|
||||
(void)free(chars), chars = NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -158,7 +164,6 @@
|
||||
floatCount:1
|
||||
charCount:(NSUInteger)strl
|
||||
size:&length];
|
||||
|
||||
// not sure how this ended up but nothing returned
|
||||
// even though there should had been
|
||||
if(length == 0) {
|
||||
@@ -170,12 +175,14 @@
|
||||
unit.value = floats[0];
|
||||
unit.type = IJSVGUnitLengthTypeNumber;
|
||||
|
||||
// memory free
|
||||
(void)(free(floats)), floats = NULL;
|
||||
|
||||
IJSVGUnitLengthType type = [self typeForCString:chars];
|
||||
unit.originalType = type;
|
||||
|
||||
// memory free
|
||||
(void)(free(floats)), floats = NULL;
|
||||
(void)free(chars), chars = NULL;
|
||||
|
||||
switch(type) {
|
||||
case IJSVGUnitLengthTypePercentage: {
|
||||
unit.value = [self convertUnitValue:unit.value
|
||||
@@ -191,6 +198,32 @@
|
||||
return unit;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
IJSVGUnitLength* length = [[IJSVGUnitLength alloc] init];
|
||||
length.value = self.value;
|
||||
length.type = self.type;
|
||||
length.originalType = self.originalType;
|
||||
length.inherit = self.inherit;
|
||||
return length;
|
||||
}
|
||||
|
||||
- (IJSVGUnitLength*)lengthWithUnitType:(IJSVGUnitLengthType)type
|
||||
{
|
||||
return [self.class unitWithFloat:self.value
|
||||
type:type];
|
||||
}
|
||||
|
||||
- (IJSVGUnitLength*)lengthByMatchingPercentage
|
||||
{
|
||||
if(self.type != IJSVGUnitLengthTypePercentage && self.value <= 1.f) {
|
||||
return [self.class unitWithFloat:self.value
|
||||
type:IJSVGUnitLengthTypePercentage];
|
||||
}
|
||||
return [self.class unitWithFloat:self.value
|
||||
type:self.type];
|
||||
}
|
||||
|
||||
- (CGFloat)computeValue:(CGFloat)anotherValue
|
||||
{
|
||||
if (self.type == IJSVGUnitLengthTypePercentage) {
|
||||
|
||||
@@ -9,9 +9,16 @@
|
||||
#import <IJSVG/IJSVGUnitLength.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGUnitPoint : NSObject
|
||||
@interface IJSVGUnitPoint : NSObject <NSCopying>
|
||||
|
||||
@property (nonatomic, retain) IJSVGUnitLength* x;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* y;
|
||||
@property (nonatomic, readonly) CGPoint value;
|
||||
|
||||
+ (IJSVGUnitPoint*)pointWithX:(IJSVGUnitLength*)x
|
||||
y:(IJSVGUnitLength*)y;
|
||||
|
||||
- (void)convertUnitsToLengthType:(IJSVGUnitLengthType)lengthType;
|
||||
- (CGPoint)computeValue:(CGSize)size;
|
||||
|
||||
@end
|
||||
|
||||
@@ -26,4 +26,28 @@
|
||||
return point;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
IJSVGUnitPoint* point = [[self.class alloc] init];
|
||||
point.x = [_x.copy autorelease];
|
||||
point.y = [_y.copy autorelease];
|
||||
return point;
|
||||
}
|
||||
|
||||
- (void)convertUnitsToLengthType:(IJSVGUnitLengthType)lengthType
|
||||
{
|
||||
_x.type = _y.type = lengthType;
|
||||
}
|
||||
|
||||
- (CGPoint)computeValue:(CGSize)size
|
||||
{
|
||||
return CGPointMake([_x computeValue:size.width],
|
||||
[_y computeValue:size.height]);
|
||||
}
|
||||
|
||||
- (CGPoint)value
|
||||
{
|
||||
return [self computeValue:CGSizeZero];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,12 +10,24 @@
|
||||
#import <IJSVG/IJSVGUnitSize.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGUnitRect : NSObject
|
||||
@interface IJSVGUnitRect : NSObject <NSCopying>
|
||||
|
||||
@property (nonatomic, retain) IJSVGUnitSize* size;
|
||||
@property (nonatomic, retain) IJSVGUnitPoint* origin;
|
||||
@property (nonatomic, readonly) BOOL isZeroRect;
|
||||
@property (nonatomic, readonly) CGRect value;
|
||||
|
||||
+ (IJSVGUnitRect*)rectWithCGRect:(CGRect)rect;
|
||||
+ (IJSVGUnitRect*)rectWithOrigin:(IJSVGUnitPoint*)origin
|
||||
size:(IJSVGUnitSize*)size;
|
||||
+ (IJSVGUnitRect*)rectWithX:(CGFloat)x
|
||||
y:(CGFloat)y
|
||||
width:(CGFloat)width
|
||||
height:(CGFloat)height;
|
||||
|
||||
- (CGRect)computeValue:(CGSize)size;
|
||||
|
||||
- (IJSVGUnitRect*)copyByConvertingToUnitsLengthType:(IJSVGUnitLengthType)type;
|
||||
- (void)convertUnitsLengthType:(IJSVGUnitLengthType)type;
|
||||
|
||||
@end
|
||||
|
||||
@@ -26,4 +26,65 @@
|
||||
return rect;
|
||||
}
|
||||
|
||||
+ (IJSVGUnitRect*)rectWithCGRect:(CGRect)rect
|
||||
{
|
||||
return [self rectWithX:rect.origin.x
|
||||
y:rect.origin.y
|
||||
width:rect.size.width
|
||||
height:rect.size.height];
|
||||
}
|
||||
|
||||
+ (IJSVGUnitRect*)rectWithX:(CGFloat)x
|
||||
y:(CGFloat)y
|
||||
width:(CGFloat)width
|
||||
height:(CGFloat)height
|
||||
{
|
||||
IJSVGUnitPoint* origin = [IJSVGUnitPoint pointWithX:[IJSVGUnitLength unitWithFloat:x]
|
||||
y:[IJSVGUnitLength unitWithFloat:y]];
|
||||
IJSVGUnitSize* size = [IJSVGUnitSize sizeWithWidth:[IJSVGUnitLength unitWithFloat:width]
|
||||
height:[IJSVGUnitLength unitWithFloat:height]];
|
||||
return [self rectWithOrigin:origin
|
||||
size:size];
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
IJSVGUnitRect* rect = [[self.class alloc] init];
|
||||
rect.size = [_size.copy autorelease];
|
||||
rect.origin = [_origin.copy autorelease];
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (CGRect)computeValue:(CGSize)size
|
||||
{
|
||||
return CGRectMake([_origin.x computeValue:size.width],
|
||||
[_origin.y computeValue:size.height],
|
||||
[_size.width computeValue:size.width],
|
||||
[_size.height computeValue:size.height]);
|
||||
}
|
||||
|
||||
- (BOOL)isZeroRect
|
||||
{
|
||||
CGRect computed = [self computeValue:CGSizeZero];
|
||||
return CGRectIsNull(computed) == YES || CGRectEqualToRect(computed, CGRectZero);
|
||||
}
|
||||
|
||||
- (IJSVGUnitRect*)copyByConvertingToUnitsLengthType:(IJSVGUnitLengthType)type
|
||||
{
|
||||
IJSVGUnitRect* rect = self.copy;
|
||||
[rect convertUnitsLengthType:type];
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (void)convertUnitsLengthType:(IJSVGUnitLengthType)type
|
||||
{
|
||||
[_origin convertUnitsToLengthType:type];
|
||||
[_size convertUnitsToLengthType:type];
|
||||
}
|
||||
|
||||
- (CGRect)value
|
||||
{
|
||||
return [self computeValue:CGSizeZero];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,12 +9,16 @@
|
||||
#import <IJSVG/IJSVGUnitLength.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGUnitSize : NSObject
|
||||
@interface IJSVGUnitSize : NSObject <NSCopying>
|
||||
|
||||
@property (nonatomic, retain) IJSVGUnitLength* width;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* height;
|
||||
@property (nonatomic, readonly) CGSize value;
|
||||
|
||||
+ (IJSVGUnitSize*)sizeWithWidth:(IJSVGUnitLength*)width
|
||||
height:(IJSVGUnitLength*)height;
|
||||
|
||||
- (void)convertUnitsToLengthType:(IJSVGUnitLengthType)lengthType;
|
||||
- (CGSize)computeValue:(CGSize)size;
|
||||
|
||||
@end
|
||||
|
||||
@@ -26,4 +26,29 @@
|
||||
return size;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
IJSVGUnitSize* size = [[self.class alloc] init];
|
||||
size.width = [_width.copy autorelease];
|
||||
size.height = [_height.copy autorelease];
|
||||
return size;
|
||||
}
|
||||
|
||||
- (void)convertUnitsToLengthType:(IJSVGUnitLengthType)lengthType
|
||||
{
|
||||
_width.type = _height.type = lengthType;
|
||||
}
|
||||
|
||||
- (CGSize)computeValue:(CGSize)size
|
||||
{
|
||||
return CGSizeMake([_width computeValue:size.width],
|
||||
[_height computeValue:size.height]);
|
||||
}
|
||||
|
||||
- (CGSize)value
|
||||
{
|
||||
return [self computeValue:CGSizeZero];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#import <IJSVG/IJSVGGradientUnitLength.h>
|
||||
#import <IJSVG/IJSVGStringAdditions.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@@ -24,9 +25,11 @@ CGFloat degrees_to_radians(CGFloat degrees);
|
||||
BOOL IJSVGCharBufferIsHEX(char* buffer);
|
||||
BOOL IJSVGCharBufferHasPrefix(char* pre, char* str);
|
||||
BOOL IJSVGCharBufferHasSuffix(char* s1, char* s2);
|
||||
char* IJSVGTimmedCharBufferCreate(const char* buffer);
|
||||
void IJSVGTrimCharBuffer(char* buffer);
|
||||
void IJSVGCharBufferToLower(char* buffer);
|
||||
size_t IJSVGCharBufferHash(char* buffer);
|
||||
CGPoint IJSVGPathGetLastQuadraticCommandPoint(CGPathRef path);
|
||||
|
||||
IJSVGFloatingPointOptions IJSVGFloatingPointOptionsDefault(void);
|
||||
IJSVGFloatingPointOptions IJSVGFloatingPointOptionsMake(BOOL round, int precision);
|
||||
@@ -75,5 +78,10 @@ BOOL IJSVGIsSVGLayer(CALayer* layer);
|
||||
weight:(CGFloat*)weight;
|
||||
|
||||
+ (CGPathRef)newFlippedCGPath:(CGPathRef)path;
|
||||
|
||||
+ (CAShapeLayerLineJoin)CGLineJoinForJoinStyle:(IJSVGLineJoinStyle)joinStyle;
|
||||
+ (CAShapeLayerLineCap)CGLineCapForCapStyle:(IJSVGLineCapStyle)capStyle;
|
||||
+ (CAShapeLayerFillRule)CGFillRuleForWindingRule:(IJSVGWindingRule)rule;
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -43,8 +43,23 @@ BOOL IJSVGCharBufferHasSuffix(char* s1, char* s2)
|
||||
return strcmp(s1 + slen - tlen, s2) == 0;
|
||||
}
|
||||
|
||||
void IJSVGTrimCharBuffer(char* buffer)
|
||||
char* IJSVGTimmedCharBufferCreate(const char* buffer)
|
||||
{
|
||||
unsigned long start = 0;
|
||||
unsigned long length = strlen(buffer);
|
||||
while(length-1 > 0 && isspace(buffer[length-1])) {
|
||||
length--;
|
||||
}
|
||||
while(isspace(buffer[start])) {
|
||||
start++;
|
||||
}
|
||||
char* chars = (char*)malloc(sizeof(char)*((length-start)+1) ?: sizeof(char));
|
||||
memcpy(chars, &buffer[start], length-start);
|
||||
chars[length] = '\0';
|
||||
return chars;
|
||||
}
|
||||
|
||||
void IJSVGTrimCharBuffer(char* buffer) {
|
||||
char* ptr = buffer;
|
||||
unsigned long length = strlen(ptr);
|
||||
while(length-1 > 0 && isspace(ptr[length-1])) {
|
||||
@@ -177,6 +192,27 @@ BOOL IJSVGIsLegalCommandCharacter(unichar aChar)
|
||||
return NO;
|
||||
}
|
||||
|
||||
void IJSVGPathGetLastQuadraticCommandPointEnumerationCallback(void *info, const CGPathElement *element)
|
||||
{
|
||||
// this will just iterate over the path and keep changing the point
|
||||
// when we come across a quad curve, we cant break when we find one as we
|
||||
// dont know when the last one is.
|
||||
CGPoint* point = (CGPoint*)info;
|
||||
if(element->type == kCGPathElementAddQuadCurveToPoint) {
|
||||
CGPoint curvePoint = element->points[0];
|
||||
point->x = curvePoint.x;
|
||||
point->y = curvePoint.y;
|
||||
}
|
||||
}
|
||||
|
||||
CGPoint IJSVGPathGetLastQuadraticCommandPoint(CGPathRef path)
|
||||
{
|
||||
CGPoint point = CGPointZero;
|
||||
CGPathApply(path, &point,
|
||||
IJSVGPathGetLastQuadraticCommandPointEnumerationCallback);
|
||||
return point;
|
||||
}
|
||||
|
||||
BOOL IJSVGIsSVGLayer(CALayer* layer)
|
||||
{
|
||||
return [layer isKindOfClass:IJSVGLayer.class] ||
|
||||
@@ -235,7 +271,7 @@ CGFloat degrees_to_radians(CGFloat degrees)
|
||||
const char* str = string.UTF8String;
|
||||
NSUInteger count = 0;
|
||||
IJSVGParsingStringMethod** methods;
|
||||
methods = IJSVGParsingMethodParseString((char*)str, &count);
|
||||
methods = IJSVGParsingMethodParseString(str, &count);
|
||||
if(count == 0) {
|
||||
IJSVGParsingStringMethodsRelease(methods, count);
|
||||
return nil;
|
||||
@@ -541,4 +577,50 @@ CGFloat degrees_to_radians(CGFloat degrees)
|
||||
return transformPath;
|
||||
}
|
||||
|
||||
#pragma mark CG conversions
|
||||
|
||||
+ (CAShapeLayerLineJoin)CGLineJoinForJoinStyle:(IJSVGLineJoinStyle)joinStyle
|
||||
{
|
||||
switch (joinStyle) {
|
||||
default:
|
||||
case IJSVGLineJoinStyleMiter: {
|
||||
return kCALineJoinMiter;
|
||||
}
|
||||
case IJSVGLineJoinStyleBevel: {
|
||||
return kCALineJoinBevel;
|
||||
}
|
||||
case IJSVGLineJoinStyleRound: {
|
||||
return kCALineJoinRound;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (CAShapeLayerLineCap)CGLineCapForCapStyle:(IJSVGLineCapStyle)capStyle
|
||||
{
|
||||
switch (capStyle) {
|
||||
default:
|
||||
case IJSVGLineCapStyleButt: {
|
||||
return kCALineCapButt;
|
||||
}
|
||||
case IJSVGLineCapStyleRound: {
|
||||
return kCALineCapRound;
|
||||
}
|
||||
case IJSVGLineCapStyleSquare: {
|
||||
return kCALineCapSquare;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (CAShapeLayerFillRule)CGFillRuleForWindingRule:(IJSVGWindingRule)rule
|
||||
{
|
||||
switch (rule) {
|
||||
case IJSVGWindingRuleEvenOdd: {
|
||||
return kCAFillRuleEvenOdd;
|
||||
}
|
||||
default: {
|
||||
return kCAFillRuleNonZero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// IJSVGViewBox.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 14/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Quartz/Quartz.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, IJSVGViewBoxAlignment) {
|
||||
IJSVGViewBoxAlignmentUnknown,
|
||||
IJSVGViewBoxAlignmentNone,
|
||||
IJSVGViewBoxAlignmentXMinYMin,
|
||||
IJSVGViewBoxAlignmentXMidYMin,
|
||||
IJSVGViewBoxAlignmentXMaxYMin,
|
||||
IJSVGViewBoxAlignmentXMinYMid,
|
||||
IJSVGViewBoxAlignmentXMidYMid,
|
||||
IJSVGViewBoxAlignmentXMaxYMid,
|
||||
IJSVGViewBoxAlignmentXMinYMax,
|
||||
IJSVGViewBoxAlignmentXMidYMax,
|
||||
IJSVGViewBoxAlignmentXMaxYMax,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, IJSVGViewBoxMeetOrSlice) {
|
||||
IJSVGViewBoxMeetOrSliceUnknown,
|
||||
IJSVGViewBoxMeetOrSliceMeet,
|
||||
IJSVGViewBoxMeetOrSliceSlice,
|
||||
};
|
||||
|
||||
@interface IJSVGViewBox : NSObject
|
||||
|
||||
typedef void (^IJSVGViewBoxDrawingBlock)(CGSize scale);
|
||||
|
||||
+ (IJSVGViewBoxAlignment)alignmentForString:(NSString*)string
|
||||
meetOrSlice:(IJSVGViewBoxMeetOrSlice*)meetOrSlice;
|
||||
+ (IJSVGViewBoxAlignment)alignmentForString:(NSString*)string;
|
||||
+ (IJSVGViewBoxMeetOrSlice)meetOrSliceForString:(NSString*)string;
|
||||
|
||||
+ (void)drawViewBox:(CGRect)viewBox
|
||||
inRect:(CGRect)drawingRect
|
||||
alignment:(IJSVGViewBoxAlignment)alignment
|
||||
meetOrSlice:(IJSVGViewBoxMeetOrSlice)meetOrSlice
|
||||
inContext:(CGContextRef)ctx
|
||||
drawingBlock:(IJSVGViewBoxDrawingBlock)block;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,382 @@
|
||||
//
|
||||
// IJSVGViewBox.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 14/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGViewBox.h"
|
||||
#import "IJSVGStringAdditions.h"
|
||||
|
||||
@implementation IJSVGViewBox
|
||||
|
||||
+ (IJSVGViewBoxAlignment)alignmentForString:(NSString*)string
|
||||
meetOrSlice:(IJSVGViewBoxMeetOrSlice*)meetOrSlice
|
||||
{
|
||||
NSArray<NSString*>* parts = [string ijsvg_componentsSplitByWhiteSpace];
|
||||
if(parts.count == 1) {
|
||||
*meetOrSlice = IJSVGViewBoxMeetOrSliceMeet;
|
||||
return [self alignmentForString:parts[0]];
|
||||
}
|
||||
*meetOrSlice = [self meetOrSliceForString:parts[1]];
|
||||
return [self alignmentForString:parts[0]];
|
||||
}
|
||||
|
||||
+ (IJSVGViewBoxMeetOrSlice)meetOrSliceForString:(NSString*)string
|
||||
{
|
||||
if(string == nil) {
|
||||
return IJSVGViewBoxMeetOrSliceUnknown;
|
||||
}
|
||||
|
||||
const char* name = string.lowercaseString.UTF8String;
|
||||
if(name == NULL) {
|
||||
return IJSVGViewBoxMeetOrSliceUnknown;
|
||||
}
|
||||
if(strcmp(name, "meet") == 0) {
|
||||
return IJSVGViewBoxMeetOrSliceMeet;
|
||||
}
|
||||
if(strcmp(name, "slice") == 0) {
|
||||
return IJSVGViewBoxMeetOrSliceSlice;
|
||||
}
|
||||
return IJSVGViewBoxMeetOrSliceUnknown;
|
||||
}
|
||||
|
||||
+ (IJSVGViewBoxAlignment)alignmentForString:(NSString*)string
|
||||
{
|
||||
if(string == nil) {
|
||||
return IJSVGViewBoxAlignmentUnknown;
|
||||
}
|
||||
|
||||
const char* name = string.lowercaseString.UTF8String;
|
||||
if(name == NULL) {
|
||||
return IJSVGViewBoxAlignmentUnknown;
|
||||
}
|
||||
if(strcmp(name, "none") == 0) {
|
||||
return IJSVGViewBoxAlignmentNone;
|
||||
}
|
||||
if(strcmp(name, "xminymin") == 0) {
|
||||
return IJSVGViewBoxAlignmentXMinYMin;
|
||||
}
|
||||
if(strcmp(name, "xmidymin") == 0) {
|
||||
return IJSVGViewBoxAlignmentXMidYMin;
|
||||
}
|
||||
if(strcmp(name, "xmaxymin") == 0) {
|
||||
return IJSVGViewBoxAlignmentXMaxYMin;
|
||||
}
|
||||
if(strcmp(name, "xminymid") == 0) {
|
||||
return IJSVGViewBoxAlignmentXMinYMid;
|
||||
}
|
||||
if(strcmp(name, "xmidymid") == 0) {
|
||||
return IJSVGViewBoxAlignmentXMidYMid;
|
||||
}
|
||||
if(strcmp(name, "xmaxymid") == 0) {
|
||||
return IJSVGViewBoxAlignmentXMaxYMid;
|
||||
}
|
||||
if(strcmp(name, "xminymax") == 0) {
|
||||
return IJSVGViewBoxAlignmentXMinYMax;
|
||||
}
|
||||
if(strcmp(name, "xmidymax") == 0) {
|
||||
return IJSVGViewBoxAlignmentXMidYMax;
|
||||
}
|
||||
if(strcmp(name, "xmaxymax") == 0) {
|
||||
return IJSVGViewBoxAlignmentXMaxYMax;
|
||||
}
|
||||
return IJSVGViewBoxAlignmentUnknown;
|
||||
}
|
||||
|
||||
CGSize IJSVGViewBoxComputeXMidYMid(CGContextRef ctx, CGRect viewBox,
|
||||
CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice)
|
||||
{
|
||||
CGFloat width = drawingRect.size.width / viewBox.size.width;
|
||||
CGFloat height = drawingRect.size.height / viewBox.size.height;
|
||||
CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height);
|
||||
|
||||
// scale the viewBox into the drawingRect
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio));
|
||||
|
||||
// translate it
|
||||
CGAffineTransform translate = CGAffineTransformMakeTranslation(drawingRect.size.width / 2.f - (viewBox.size.width * ratio) / 2.f,
|
||||
drawingRect.size.height / 2.f - (viewBox.size.height * ratio) / 2.f);
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio),
|
||||
-(viewBox.origin.y * ratio));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
|
||||
return CGSizeMake(ratio, ratio);
|
||||
}
|
||||
|
||||
CGSize IJSVGViewBoxComputeXMinYMid(CGContextRef ctx, CGRect viewBox,
|
||||
CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice)
|
||||
{
|
||||
CGFloat width = drawingRect.size.width / viewBox.size.width;
|
||||
CGFloat height = drawingRect.size.height / viewBox.size.height;
|
||||
CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height);
|
||||
|
||||
// scale the viewBox into the drawingRect
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio));
|
||||
|
||||
// translate it
|
||||
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.f,
|
||||
drawingRect.size.height / 2.f - ((viewBox.size.height * ratio)) / 2.f);
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio),
|
||||
-(viewBox.origin.y * ratio));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
|
||||
return CGSizeMake(ratio, ratio);
|
||||
}
|
||||
|
||||
CGSize IJSVGViewBoxComputeXMaxYMid(CGContextRef ctx, CGRect viewBox,
|
||||
CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice)
|
||||
{
|
||||
CGFloat width = drawingRect.size.width / viewBox.size.width;
|
||||
CGFloat height = drawingRect.size.height / viewBox.size.height;
|
||||
CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height);
|
||||
|
||||
// scale the viewBox into the drawingRect
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio));
|
||||
|
||||
// translate it
|
||||
CGAffineTransform translate = CGAffineTransformMakeTranslation(drawingRect.size.width - (viewBox.size.width * ratio),
|
||||
drawingRect.size.height / 2.f - ((viewBox.size.height * ratio)) / 2.f);
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio),
|
||||
-(viewBox.origin.y * ratio));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
|
||||
return CGSizeMake(ratio, ratio);
|
||||
}
|
||||
|
||||
CGSize IJSVGViewBoxComputeXMidYMin(CGContextRef ctx, CGRect viewBox,
|
||||
CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice)
|
||||
{
|
||||
CGFloat width = drawingRect.size.width / viewBox.size.width;
|
||||
CGFloat height = drawingRect.size.height / viewBox.size.height;
|
||||
CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height);
|
||||
|
||||
// scale the viewBox into the drawingRect
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio));
|
||||
|
||||
// translate it
|
||||
CGAffineTransform translate = CGAffineTransformMakeTranslation(drawingRect.size.width / 2.f - ((viewBox.size.width * ratio)) / 2.f,
|
||||
0.f);
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio),
|
||||
-(viewBox.origin.y * ratio));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
|
||||
return CGSizeMake(ratio, ratio);
|
||||
}
|
||||
|
||||
CGSize IJSVGViewBoxComputeXMinYMin(CGContextRef ctx, CGRect viewBox,
|
||||
CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice)
|
||||
{
|
||||
CGFloat width = drawingRect.size.width / viewBox.size.width;
|
||||
CGFloat height = drawingRect.size.height / viewBox.size.height;
|
||||
CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height);
|
||||
|
||||
// scale the viewBox into the drawingRect
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio));
|
||||
|
||||
// translate it
|
||||
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.f, 0.f);
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio),
|
||||
-(viewBox.origin.y * ratio));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
|
||||
return CGSizeMake(ratio, ratio);
|
||||
}
|
||||
|
||||
CGSize IJSVGViewBoxComputeXMidYMax(CGContextRef ctx, CGRect viewBox,
|
||||
CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice)
|
||||
{
|
||||
CGFloat width = drawingRect.size.width / viewBox.size.width;
|
||||
CGFloat height = drawingRect.size.height / viewBox.size.height;
|
||||
CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height);
|
||||
|
||||
// scale the viewBox into the drawingRect
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio));
|
||||
|
||||
// translate it
|
||||
CGAffineTransform translate = CGAffineTransformMakeTranslation(drawingRect.size.width / 2.f - ((viewBox.size.width * ratio)) / 2.f,
|
||||
drawingRect.size.height - (viewBox.size.height * ratio));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio),
|
||||
-(viewBox.origin.y * ratio));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
|
||||
return CGSizeMake(ratio, ratio);
|
||||
}
|
||||
|
||||
CGSize IJSVGViewBoxComputeXMaxYMin(CGContextRef ctx, CGRect viewBox,
|
||||
CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice)
|
||||
{
|
||||
CGFloat width = drawingRect.size.width / viewBox.size.width;
|
||||
CGFloat height = drawingRect.size.height / viewBox.size.height;
|
||||
CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height);
|
||||
|
||||
// scale the viewBox into the drawingRect
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio));
|
||||
|
||||
// translate it
|
||||
CGAffineTransform translate = CGAffineTransformMakeTranslation(drawingRect.size.width - viewBox.size.width,
|
||||
0.f);
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio),
|
||||
-(viewBox.origin.y * ratio));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
|
||||
return CGSizeMake(ratio, ratio);
|
||||
}
|
||||
|
||||
CGSize IJSVGViewBoxComputeXMinYMax(CGContextRef ctx, CGRect viewBox,
|
||||
CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice)
|
||||
{
|
||||
CGFloat width = drawingRect.size.width / viewBox.size.width;
|
||||
CGFloat height = drawingRect.size.height / viewBox.size.height;
|
||||
CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height);
|
||||
|
||||
// scale the viewBox into the drawingRect
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio));
|
||||
|
||||
// translate it
|
||||
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.f,
|
||||
drawingRect.size.height - viewBox.size.height);
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio),
|
||||
-(viewBox.origin.y * ratio));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
|
||||
return CGSizeMake(ratio, ratio);
|
||||
}
|
||||
|
||||
CGSize IJSVGViewBoxComputeXMaxYMax(CGContextRef ctx, CGRect viewBox,
|
||||
CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice)
|
||||
{
|
||||
CGFloat width = drawingRect.size.width / viewBox.size.width;
|
||||
CGFloat height = drawingRect.size.height / viewBox.size.height;
|
||||
CGFloat ratio = meetOrSlice == IJSVGViewBoxMeetOrSliceMeet ? MIN(width, height) : MAX(width, height);
|
||||
|
||||
// scale the viewBox into the drawingRect
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(ratio, ratio));
|
||||
|
||||
// translate it
|
||||
CGAffineTransform translate = CGAffineTransformMakeTranslation(drawingRect.size.width - viewBox.size.width,
|
||||
drawingRect.size.height - viewBox.size.height);
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * ratio),
|
||||
-(viewBox.origin.y * ratio));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
|
||||
return CGSizeMake(ratio, ratio);
|
||||
}
|
||||
|
||||
CGSize IJSVGViewBoxComputeNone(CGContextRef ctx, CGRect viewBox,
|
||||
CGRect drawingRect, IJSVGViewBoxMeetOrSlice meetOrSlice)
|
||||
{
|
||||
CGFloat width = drawingRect.size.width / viewBox.size.width;
|
||||
CGFloat height = drawingRect.size.height / viewBox.size.height;
|
||||
|
||||
// scale the viewBox into the drawingRect
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(width, height));
|
||||
|
||||
// translate it
|
||||
CGAffineTransform translate = CGAffineTransformMakeTranslation(drawingRect.size.width / 2.f - ((viewBox.size.width * width)) / 2.f,
|
||||
drawingRect.size.height - (viewBox.size.height * height));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
translate = CGAffineTransformMakeTranslation(-(viewBox.origin.x * width),
|
||||
-(viewBox.origin.y * height));
|
||||
transform = CGAffineTransformConcat(transform, translate);
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
|
||||
return CGSizeMake(width, height);
|
||||
}
|
||||
|
||||
+ (void)drawViewBox:(CGRect)viewBox
|
||||
inRect:(CGRect)drawingRect
|
||||
alignment:(IJSVGViewBoxAlignment)alignment
|
||||
meetOrSlice:(IJSVGViewBoxMeetOrSlice)meetOrSlice
|
||||
inContext:(CGContextRef)ctx
|
||||
drawingBlock:(IJSVGViewBoxDrawingBlock)block
|
||||
{
|
||||
// this is equal to none, dont do anything fancy
|
||||
if(CGRectIsNull(viewBox) == YES ||
|
||||
CGRectEqualToRect(viewBox, CGRectZero) == YES) {
|
||||
block(CGSizeMake(1.f, 1.f));
|
||||
return;
|
||||
}
|
||||
|
||||
CGContextSaveGState(ctx);
|
||||
if(meetOrSlice == IJSVGViewBoxMeetOrSliceSlice) {
|
||||
CGContextClipToRect(ctx, drawingRect);
|
||||
}
|
||||
CGSize scale = CGSizeZero;
|
||||
switch(alignment) {
|
||||
case IJSVGViewBoxAlignmentNone: {
|
||||
scale = IJSVGViewBoxComputeNone(ctx, viewBox, drawingRect, meetOrSlice);
|
||||
break;
|
||||
}
|
||||
case IJSVGViewBoxAlignmentUnknown:
|
||||
case IJSVGViewBoxAlignmentXMidYMid: {
|
||||
scale = IJSVGViewBoxComputeXMidYMid(ctx, viewBox, drawingRect, meetOrSlice);
|
||||
break;
|
||||
}
|
||||
case IJSVGViewBoxAlignmentXMinYMid: {
|
||||
scale = IJSVGViewBoxComputeXMinYMid(ctx, viewBox, drawingRect, meetOrSlice);
|
||||
break;
|
||||
}
|
||||
case IJSVGViewBoxAlignmentXMaxYMid: {
|
||||
scale = IJSVGViewBoxComputeXMaxYMid(ctx, viewBox, drawingRect, meetOrSlice);
|
||||
break;
|
||||
}
|
||||
case IJSVGViewBoxAlignmentXMidYMin: {
|
||||
scale = IJSVGViewBoxComputeXMidYMin(ctx, viewBox, drawingRect, meetOrSlice);
|
||||
break;
|
||||
}
|
||||
case IJSVGViewBoxAlignmentXMidYMax: {
|
||||
scale = IJSVGViewBoxComputeXMidYMax(ctx, viewBox, drawingRect, meetOrSlice);
|
||||
break;
|
||||
}
|
||||
case IJSVGViewBoxAlignmentXMinYMin: {
|
||||
scale = IJSVGViewBoxComputeXMinYMin(ctx, viewBox, drawingRect, meetOrSlice);
|
||||
break;
|
||||
}
|
||||
case IJSVGViewBoxAlignmentXMaxYMin: {
|
||||
scale = IJSVGViewBoxComputeXMaxYMin(ctx, viewBox, drawingRect, meetOrSlice);
|
||||
break;
|
||||
}
|
||||
case IJSVGViewBoxAlignmentXMinYMax: {
|
||||
scale = IJSVGViewBoxComputeXMinYMax(ctx, viewBox, drawingRect, meetOrSlice);
|
||||
break;
|
||||
}
|
||||
case IJSVGViewBoxAlignmentXMaxYMax: {
|
||||
scale = IJSVGViewBoxComputeXMaxYMax(ctx, viewBox, drawingRect, meetOrSlice);
|
||||
break;
|
||||
}
|
||||
}
|
||||
block(scale);
|
||||
CGContextRestoreGState(ctx);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -7,7 +7,6 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
343A19181FB2212C000652A2 /* IJSVGGradientUnitLength.m in Sources */ = {isa = PBXBuildFile; fileRef = 343A19171FB2212C000652A2 /* IJSVGGradientUnitLength.m */; };
|
||||
59069A2922D0ED85004DDEA5 /* compuserver_msn_Ford_Focus.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59069A2822D0ED85004DDEA5 /* compuserver_msn_Ford_Focus.svg */; };
|
||||
59069A2B22D0EE0E004DDEA5 /* test (1).svg in Resources */ = {isa = PBXBuildFile; fileRef = 59069A2A22D0EE0E004DDEA5 /* test (1).svg */; };
|
||||
590C87EB201F9888004A1554 /* json.svg in Resources */ = {isa = PBXBuildFile; fileRef = 590C87EA201F9888004A1554 /* json.svg */; };
|
||||
@@ -16,84 +15,32 @@
|
||||
590C87F1201FBF27004A1554 /* AJ_Digital_Camera.svg in Resources */ = {isa = PBXBuildFile; fileRef = 590C87F0201FBF27004A1554 /* AJ_Digital_Camera.svg */; };
|
||||
590C87F4201FC9E4004A1554 /* radialgradient2.svg in Resources */ = {isa = PBXBuildFile; fileRef = 590C87F3201FC9E3004A1554 /* radialgradient2.svg */; };
|
||||
590C87F6201FD0D4004A1554 /* car.svg in Resources */ = {isa = PBXBuildFile; fileRef = 590C87F5201FD0D4004A1554 /* car.svg */; };
|
||||
591704CC1E2016E400012644 /* IJSVGExporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 591704CB1E2016E400012644 /* IJSVGExporter.m */; };
|
||||
591A13E11E19838F001D1629 /* IJSVGText.m in Sources */ = {isa = PBXBuildFile; fileRef = 591A13E01E19838F001D1629 /* IJSVGText.m */; };
|
||||
59265CE81C4F840400F333F0 /* css.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59265CE71C4F840400F333F0 /* css.svg */; };
|
||||
59265CEB1C4F843E00F333F0 /* SVGExampleView6.m in Sources */ = {isa = PBXBuildFile; fileRef = 59265CEA1C4F843E00F333F0 /* SVGExampleView6.m */; };
|
||||
592840B11E153F3D002F9AF0 /* IJSVGLayerTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 592840B01E153F3D002F9AF0 /* IJSVGLayerTree.m */; };
|
||||
592840B41E155308002F9AF0 /* IJSVGGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 592840B31E155308002F9AF0 /* IJSVGGradientLayer.m */; };
|
||||
5941DAFD1CF9BC9B00B3A911 /* IJSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 5941DAFA1CF9BC9B00B3A911 /* IJSVGImage.m */; };
|
||||
5941DAFE1CF9BC9B00B3A911 /* IJSVGPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 5941DAFC1CF9BC9B00B3A911 /* IJSVGPattern.m */; };
|
||||
59459CEC19B906FE00CE493B /* clipped.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59459CEB19B906FE00CE493B /* clipped.svg */; };
|
||||
59459CEF19B9074F00CE493B /* SVGExampleView4.m in Sources */ = {isa = PBXBuildFile; fileRef = 59459CEE19B9074F00CE493B /* SVGExampleView4.m */; };
|
||||
5948DED51BB2BFE5004156FF /* IJSVGFontConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5948DED21BB2BFE5004156FF /* IJSVGFontConverter.m */; };
|
||||
5948DED61BB2BFE5004156FF /* IJSVGWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5948DED41BB2BFE5004156FF /* IJSVGWriter.m */; };
|
||||
5956657D19B62F4600D805FF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956657C19B62F4600D805FF /* main.m */; };
|
||||
5956658019B62F4600D805FF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956657F19B62F4600D805FF /* AppDelegate.m */; };
|
||||
5956658219B62F4600D805FF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5956658119B62F4600D805FF /* Images.xcassets */; };
|
||||
5956658519B62F4600D805FF /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5956658319B62F4600D805FF /* MainMenu.xib */; };
|
||||
5956659119B62F4700D805FF /* IJSVGExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956659019B62F4700D805FF /* IJSVGExampleTests.m */; };
|
||||
595665DC19B6302600D805FF /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = 595665C619B6302600D805FF /* README.md */; };
|
||||
595665DE19B6309C00D805FF /* test.svg in Resources */ = {isa = PBXBuildFile; fileRef = 595665DD19B6309C00D805FF /* test.svg */; };
|
||||
595665E119B630B600D805FF /* SVGView.m in Sources */ = {isa = PBXBuildFile; fileRef = 595665E019B630B600D805FF /* SVGView.m */; };
|
||||
597046A21E24352700A60138 /* IJSVGStrokeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 597046A11E24352700A60138 /* IJSVGStrokeLayer.m */; };
|
||||
597AC83322CFD0FC007C0E42 /* home.svg in Resources */ = {isa = PBXBuildFile; fileRef = 597AC83222CFD0FC007C0E42 /* home.svg */; };
|
||||
5986308719BA104800CF15EA /* linecap.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5986308619BA104800CF15EA /* linecap.svg */; };
|
||||
5986308A19BA106D00CF15EA /* SVGExampleView5.m in Sources */ = {isa = PBXBuildFile; fileRef = 5986308919BA106D00CF15EA /* SVGExampleView5.m */; };
|
||||
5986308C19BA180E00CF15EA /* dashed.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5986308B19BA180E00CF15EA /* dashed.svg */; };
|
||||
598759F61E242C850024CC3F /* IJSVGExporterPathInstruction.m in Sources */ = {isa = PBXBuildFile; fileRef = 598759F51E242C850024CC3F /* IJSVGExporterPathInstruction.m */; };
|
||||
5991A2A9201E30E600913E3B /* gradients.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5991A2A8201E30E600913E3B /* gradients.svg */; };
|
||||
5991A2AB201E310200913E3B /* heart.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5991A2AA201E310200913E3B /* heart.svg */; };
|
||||
599465DC1C4AA87200A2EEF3 /* IJSVGStyleSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 599465D51C4AA87200A2EEF3 /* IJSVGStyleSheet.m */; };
|
||||
599465DD1C4AA87200A2EEF3 /* IJSVGStyleSheetRule.m in Sources */ = {isa = PBXBuildFile; fileRef = 599465D71C4AA87200A2EEF3 /* IJSVGStyleSheetRule.m */; };
|
||||
599465DE1C4AA87200A2EEF3 /* IJSVGStyleSheetSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 599465D91C4AA87200A2EEF3 /* IJSVGStyleSheetSelector.m */; };
|
||||
599465DF1C4AA87200A2EEF3 /* IJSVGStyleSheetSelectorRaw.m in Sources */ = {isa = PBXBuildFile; fileRef = 599465DB1C4AA87200A2EEF3 /* IJSVGStyleSheetSelectorRaw.m */; };
|
||||
59A11E6C19B89CEA00E44498 /* SVGExampleView1.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A11E6B19B89CEA00E44498 /* SVGExampleView1.m */; };
|
||||
59A11E6F19B89D2000E44498 /* SVGExampleView2.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A11E6E19B89D2000E44498 /* SVGExampleView2.m */; };
|
||||
59A11E7219B89D6600E44498 /* SVGExampleView3.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A11E7119B89D6600E44498 /* SVGExampleView3.m */; };
|
||||
59A3DA6D1E283022003E59A9 /* IJSVGTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A3DA6C1E283022003E59A9 /* IJSVGTransaction.m */; };
|
||||
59B93C6D19B7D1840063E823 /* paperplane.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59B93C6C19B7D1840063E823 /* paperplane.svg */; };
|
||||
59B93C6F19B7D32C0063E823 /* products.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59B93C6E19B7D32C0063E823 /* products.svg */; };
|
||||
59D1E3A0202279CA00C54672 /* Group.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59D1E39F202279CA00C54672 /* Group.svg */; };
|
||||
59E0F5ED1E29964700F757F7 /* IJSVGUnitLength.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E0F5EC1E29964700F757F7 /* IJSVGUnitLength.m */; };
|
||||
59E2645119BA240D008A6FDB /* IJSVG.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2641C19BA240D008A6FDB /* IJSVG.m */; };
|
||||
59E2645219BA240D008A6FDB /* IJSVGBezierPathAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2641E19BA240D008A6FDB /* IJSVGBezierPathAdditions.m */; };
|
||||
59E2645319BA240D008A6FDB /* IJSVGCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2642019BA240D008A6FDB /* IJSVGCache.m */; };
|
||||
59E2645419BA240D008A6FDB /* IJSVGColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2642219BA240D008A6FDB /* IJSVGColor.m */; };
|
||||
59E2645519BA240D008A6FDB /* IJSVGCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2642419BA240D008A6FDB /* IJSVGCommand.m */; };
|
||||
59E2645619BA240D008A6FDB /* IJSVGCommandArc.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2642619BA240D008A6FDB /* IJSVGCommandArc.m */; };
|
||||
59E2645719BA240D008A6FDB /* IJSVGCommandClose.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2642819BA240D008A6FDB /* IJSVGCommandClose.m */; };
|
||||
59E2645819BA240D008A6FDB /* IJSVGCommandCommandSmoothQuadraticCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2642A19BA240D008A6FDB /* IJSVGCommandCommandSmoothQuadraticCurve.m */; };
|
||||
59E2645919BA240D008A6FDB /* IJSVGCommandCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2642C19BA240D008A6FDB /* IJSVGCommandCurve.m */; };
|
||||
59E2645A19BA240D008A6FDB /* IJSVGCommandHorizontalLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2642E19BA240D008A6FDB /* IJSVGCommandHorizontalLine.m */; };
|
||||
59E2645B19BA240D008A6FDB /* IJSVGCommandLineTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2643019BA240D008A6FDB /* IJSVGCommandLineTo.m */; };
|
||||
59E2645C19BA240D008A6FDB /* IJSVGCommandMove.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2643219BA240D008A6FDB /* IJSVGCommandMove.m */; };
|
||||
59E2645D19BA240D008A6FDB /* IJSVGCommandQuadraticCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2643419BA240D008A6FDB /* IJSVGCommandQuadraticCurve.m */; };
|
||||
59E2645E19BA240D008A6FDB /* IJSVGCommandSmoothCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2643619BA240D008A6FDB /* IJSVGCommandSmoothCurve.m */; };
|
||||
59E2645F19BA240D008A6FDB /* IJSVGCommandVerticalLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2643819BA240D008A6FDB /* IJSVGCommandVerticalLine.m */; };
|
||||
59E2646019BA240D008A6FDB /* IJSVGDef.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2643A19BA240D008A6FDB /* IJSVGDef.m */; };
|
||||
59E2646119BA240D008A6FDB /* IJSVGForeignObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2643C19BA240D008A6FDB /* IJSVGForeignObject.m */; };
|
||||
59E2646219BA240D008A6FDB /* IJSVGGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2643E19BA240D008A6FDB /* IJSVGGradient.m */; };
|
||||
59E2646319BA240D008A6FDB /* IJSVGGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2644019BA240D008A6FDB /* IJSVGGroup.m */; };
|
||||
59E2646419BA240D008A6FDB /* IJSVGLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2644219BA240D008A6FDB /* IJSVGLinearGradient.m */; };
|
||||
59E2646519BA240D008A6FDB /* IJSVGNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2644419BA240D008A6FDB /* IJSVGNode.m */; };
|
||||
59E2646619BA240D008A6FDB /* IJSVGParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2644619BA240D008A6FDB /* IJSVGParser.m */; };
|
||||
59E2646719BA240D008A6FDB /* IJSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2644819BA240D008A6FDB /* IJSVGPath.m */; };
|
||||
59E2646819BA240D008A6FDB /* IJSVGRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2644A19BA240D008A6FDB /* IJSVGRadialGradient.m */; };
|
||||
59E2646919BA240D008A6FDB /* IJSVGStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2644C19BA240D008A6FDB /* IJSVGStyle.m */; };
|
||||
59E2646A19BA240D008A6FDB /* IJSVGTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2644E19BA240D008A6FDB /* IJSVGTransform.m */; };
|
||||
59E2646B19BA240D008A6FDB /* IJSVGUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2645019BA240D008A6FDB /* IJSVGUtils.m */; };
|
||||
59E8ABEA1E2102A30032A80C /* IJSVGPatternLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E8ABE91E2102A30032A80C /* IJSVGPatternLayer.m */; };
|
||||
59E8ABED1E211EBE0032A80C /* IJSVGLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E8ABEC1E211EBE0032A80C /* IJSVGLayer.m */; };
|
||||
59E8ABF01E211EDB0032A80C /* IJSVGShapeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E8ABEF1E211EDB0032A80C /* IJSVGShapeLayer.m */; };
|
||||
59E8ABF31E2167D90032A80C /* IJSVGImageLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E8ABF21E2167D90032A80C /* IJSVGImageLayer.m */; };
|
||||
59E8ABF61E2176340032A80C /* IJSVGGroupLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E8ABF51E2176340032A80C /* IJSVGGroupLayer.m */; };
|
||||
59E8ABF91E219C860032A80C /* IJSVGMath.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E8ABF81E219C860032A80C /* IJSVGMath.m */; };
|
||||
59EA311622CF395400DAB3B7 /* IJSVGStringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EA310F22CF395400DAB3B7 /* IJSVGStringAdditions.m */; };
|
||||
59EA311722CF395400DAB3B7 /* IJSVGRendering.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EA311022CF395400DAB3B7 /* IJSVGRendering.m */; };
|
||||
59EA311822CF395400DAB3B7 /* IJSVGImageRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EA311322CF395400DAB3B7 /* IJSVGImageRep.m */; };
|
||||
59EA311922CF395400DAB3B7 /* IJSVGView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EA311422CF395400DAB3B7 /* IJSVGView.m */; };
|
||||
59F799E219B880CE00096CB7 /* htc_one.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59F799E119B880CE00096CB7 /* htc_one.svg */; };
|
||||
59FB54BE280B03E600D148FA /* IJSVG.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 59FB54B8280B038200D148FA /* IJSVG.framework */; };
|
||||
59FB54C0280B03F400D148FA /* IJSVG.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 59FB54B8280B038200D148FA /* IJSVG.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -104,11 +51,36 @@
|
||||
remoteGlobalIDString = 5956657619B62F4600D805FF;
|
||||
remoteInfo = IJSVGExample;
|
||||
};
|
||||
59FB54B7280B038200D148FA /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 59FB54B3280B038200D148FA /* IJSVG.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 594CF46F238FF38E009B251B;
|
||||
remoteInfo = IJSVG;
|
||||
};
|
||||
59FB54BB280B03E100D148FA /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 59FB54B3280B038200D148FA /* IJSVG.xcodeproj */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 594CF46E238FF38E009B251B;
|
||||
remoteInfo = IJSVG;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
59FB54BF280B03EE00D148FA /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
59FB54C0280B03F400D148FA /* IJSVG.framework in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
343A19161FB2212C000652A2 /* IJSVGGradientUnitLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGradientUnitLength.h; sourceTree = "<group>"; };
|
||||
343A19171FB2212C000652A2 /* IJSVGGradientUnitLength.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGradientUnitLength.m; sourceTree = "<group>"; };
|
||||
59069A2822D0ED85004DDEA5 /* compuserver_msn_Ford_Focus.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = compuserver_msn_Ford_Focus.svg; sourceTree = "<group>"; };
|
||||
59069A2A22D0EE0E004DDEA5 /* test (1).svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "test (1).svg"; sourceTree = "<group>"; };
|
||||
590C87EA201F9888004A1554 /* json.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = json.svg; sourceTree = "<group>"; };
|
||||
@@ -117,29 +89,13 @@
|
||||
590C87F0201FBF27004A1554 /* AJ_Digital_Camera.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = AJ_Digital_Camera.svg; sourceTree = "<group>"; };
|
||||
590C87F3201FC9E3004A1554 /* radialgradient2.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = radialgradient2.svg; sourceTree = "<group>"; };
|
||||
590C87F5201FD0D4004A1554 /* car.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = car.svg; sourceTree = "<group>"; };
|
||||
591704CA1E2016E400012644 /* IJSVGExporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGExporter.h; sourceTree = "<group>"; };
|
||||
591704CB1E2016E400012644 /* IJSVGExporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGExporter.m; sourceTree = "<group>"; };
|
||||
591A13DF1E19838F001D1629 /* IJSVGText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGText.h; sourceTree = "<group>"; };
|
||||
591A13E01E19838F001D1629 /* IJSVGText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGText.m; sourceTree = "<group>"; };
|
||||
59265CE71C4F840400F333F0 /* css.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = css.svg; sourceTree = "<group>"; };
|
||||
59265CE91C4F843E00F333F0 /* SVGExampleView6.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGExampleView6.h; sourceTree = "<group>"; };
|
||||
59265CEA1C4F843E00F333F0 /* SVGExampleView6.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGExampleView6.m; sourceTree = "<group>"; };
|
||||
592840AF1E153F3D002F9AF0 /* IJSVGLayerTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGLayerTree.h; sourceTree = "<group>"; };
|
||||
592840B01E153F3D002F9AF0 /* IJSVGLayerTree.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGLayerTree.m; sourceTree = "<group>"; };
|
||||
592840B21E155308002F9AF0 /* IJSVGGradientLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGradientLayer.h; sourceTree = "<group>"; };
|
||||
592840B31E155308002F9AF0 /* IJSVGGradientLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGradientLayer.m; sourceTree = "<group>"; };
|
||||
5941DAF91CF9BC9B00B3A911 /* IJSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGImage.h; sourceTree = "<group>"; };
|
||||
5941DAFA1CF9BC9B00B3A911 /* IJSVGImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGImage.m; sourceTree = "<group>"; };
|
||||
5941DAFB1CF9BC9B00B3A911 /* IJSVGPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGPattern.h; sourceTree = "<group>"; };
|
||||
5941DAFC1CF9BC9B00B3A911 /* IJSVGPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGPattern.m; sourceTree = "<group>"; };
|
||||
5934D504280C933300BEF20F /* IJSVGExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IJSVGExample.entitlements; sourceTree = "<group>"; };
|
||||
59459CEB19B906FE00CE493B /* clipped.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = clipped.svg; sourceTree = "<group>"; };
|
||||
59459CED19B9074F00CE493B /* SVGExampleView4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGExampleView4.h; sourceTree = "<group>"; };
|
||||
59459CEE19B9074F00CE493B /* SVGExampleView4.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGExampleView4.m; sourceTree = "<group>"; };
|
||||
5948DED01BB2BFE5004156FF /* IJSVGError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGError.h; sourceTree = "<group>"; };
|
||||
5948DED11BB2BFE5004156FF /* IJSVGFontConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGFontConverter.h; sourceTree = "<group>"; };
|
||||
5948DED21BB2BFE5004156FF /* IJSVGFontConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGFontConverter.m; sourceTree = "<group>"; };
|
||||
5948DED31BB2BFE5004156FF /* IJSVGWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGWriter.h; sourceTree = "<group>"; };
|
||||
5948DED41BB2BFE5004156FF /* IJSVGWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGWriter.m; sourceTree = "<group>"; };
|
||||
5956657719B62F4600D805FF /* IJSVGExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IJSVGExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
5956657B19B62F4600D805FF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
5956657C19B62F4600D805FF /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
@@ -151,117 +107,27 @@
|
||||
5956658F19B62F4700D805FF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
5956659019B62F4700D805FF /* IJSVGExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGExampleTests.m; sourceTree = "<group>"; };
|
||||
5956659A19B62F9500D805FF /* IJSVGExample-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "IJSVGExample-Prefix.pch"; sourceTree = "<group>"; };
|
||||
595665C619B6302600D805FF /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../../README.md; sourceTree = "<group>"; };
|
||||
595665DD19B6309C00D805FF /* test.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = test.svg; sourceTree = "<group>"; };
|
||||
595665DF19B630B600D805FF /* SVGView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGView.h; sourceTree = "<group>"; };
|
||||
595665E019B630B600D805FF /* SVGView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGView.m; sourceTree = "<group>"; };
|
||||
597046A01E24352700A60138 /* IJSVGStrokeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStrokeLayer.h; sourceTree = "<group>"; };
|
||||
597046A11E24352700A60138 /* IJSVGStrokeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStrokeLayer.m; sourceTree = "<group>"; };
|
||||
597AC83222CFD0FC007C0E42 /* home.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = home.svg; sourceTree = "<group>"; };
|
||||
5986308619BA104800CF15EA /* linecap.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = linecap.svg; sourceTree = "<group>"; };
|
||||
5986308819BA106D00CF15EA /* SVGExampleView5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGExampleView5.h; sourceTree = "<group>"; };
|
||||
5986308919BA106D00CF15EA /* SVGExampleView5.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGExampleView5.m; sourceTree = "<group>"; };
|
||||
5986308B19BA180E00CF15EA /* dashed.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = dashed.svg; sourceTree = "<group>"; };
|
||||
598759F41E242C850024CC3F /* IJSVGExporterPathInstruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGExporterPathInstruction.h; sourceTree = "<group>"; };
|
||||
598759F51E242C850024CC3F /* IJSVGExporterPathInstruction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGExporterPathInstruction.m; sourceTree = "<group>"; };
|
||||
5991A2A8201E30E600913E3B /* gradients.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = gradients.svg; sourceTree = "<group>"; };
|
||||
5991A2AA201E310200913E3B /* heart.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = heart.svg; sourceTree = "<group>"; };
|
||||
599465D41C4AA87200A2EEF3 /* IJSVGStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheet.h; sourceTree = "<group>"; };
|
||||
599465D51C4AA87200A2EEF3 /* IJSVGStyleSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheet.m; sourceTree = "<group>"; };
|
||||
599465D61C4AA87200A2EEF3 /* IJSVGStyleSheetRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheetRule.h; sourceTree = "<group>"; };
|
||||
599465D71C4AA87200A2EEF3 /* IJSVGStyleSheetRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheetRule.m; sourceTree = "<group>"; };
|
||||
599465D81C4AA87200A2EEF3 /* IJSVGStyleSheetSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheetSelector.h; sourceTree = "<group>"; };
|
||||
599465D91C4AA87200A2EEF3 /* IJSVGStyleSheetSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheetSelector.m; sourceTree = "<group>"; };
|
||||
599465DA1C4AA87200A2EEF3 /* IJSVGStyleSheetSelectorRaw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheetSelectorRaw.h; sourceTree = "<group>"; };
|
||||
599465DB1C4AA87200A2EEF3 /* IJSVGStyleSheetSelectorRaw.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheetSelectorRaw.m; sourceTree = "<group>"; };
|
||||
59A11E6A19B89CEA00E44498 /* SVGExampleView1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGExampleView1.h; sourceTree = "<group>"; };
|
||||
59A11E6B19B89CEA00E44498 /* SVGExampleView1.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGExampleView1.m; sourceTree = "<group>"; };
|
||||
59A11E6D19B89D2000E44498 /* SVGExampleView2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGExampleView2.h; sourceTree = "<group>"; };
|
||||
59A11E6E19B89D2000E44498 /* SVGExampleView2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGExampleView2.m; sourceTree = "<group>"; };
|
||||
59A11E7019B89D6600E44498 /* SVGExampleView3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGExampleView3.h; sourceTree = "<group>"; };
|
||||
59A11E7119B89D6600E44498 /* SVGExampleView3.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGExampleView3.m; sourceTree = "<group>"; };
|
||||
59A3DA6B1E283022003E59A9 /* IJSVGTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGTransaction.h; sourceTree = "<group>"; };
|
||||
59A3DA6C1E283022003E59A9 /* IJSVGTransaction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGTransaction.m; sourceTree = "<group>"; };
|
||||
59B93C6C19B7D1840063E823 /* paperplane.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = paperplane.svg; sourceTree = "<group>"; };
|
||||
59B93C6E19B7D32C0063E823 /* products.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = products.svg; sourceTree = "<group>"; };
|
||||
59D1E39F202279CA00C54672 /* Group.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Group.svg; sourceTree = "<group>"; };
|
||||
59E0F5EB1E29964700F757F7 /* IJSVGUnitLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGUnitLength.h; sourceTree = "<group>"; };
|
||||
59E0F5EC1E29964700F757F7 /* IJSVGUnitLength.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGUnitLength.m; sourceTree = "<group>"; };
|
||||
59E2641B19BA240D008A6FDB /* IJSVG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVG.h; sourceTree = "<group>"; };
|
||||
59E2641C19BA240D008A6FDB /* IJSVG.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVG.m; sourceTree = "<group>"; };
|
||||
59E2641D19BA240D008A6FDB /* IJSVGBezierPathAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGBezierPathAdditions.h; sourceTree = "<group>"; };
|
||||
59E2641E19BA240D008A6FDB /* IJSVGBezierPathAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGBezierPathAdditions.m; sourceTree = "<group>"; };
|
||||
59E2641F19BA240D008A6FDB /* IJSVGCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCache.h; sourceTree = "<group>"; };
|
||||
59E2642019BA240D008A6FDB /* IJSVGCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCache.m; sourceTree = "<group>"; };
|
||||
59E2642119BA240D008A6FDB /* IJSVGColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGColor.h; sourceTree = "<group>"; };
|
||||
59E2642219BA240D008A6FDB /* IJSVGColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGColor.m; sourceTree = "<group>"; };
|
||||
59E2642319BA240D008A6FDB /* IJSVGCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommand.h; sourceTree = "<group>"; };
|
||||
59E2642419BA240D008A6FDB /* IJSVGCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommand.m; sourceTree = "<group>"; };
|
||||
59E2642519BA240D008A6FDB /* IJSVGCommandArc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandArc.h; sourceTree = "<group>"; };
|
||||
59E2642619BA240D008A6FDB /* IJSVGCommandArc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandArc.m; sourceTree = "<group>"; };
|
||||
59E2642719BA240D008A6FDB /* IJSVGCommandClose.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandClose.h; sourceTree = "<group>"; };
|
||||
59E2642819BA240D008A6FDB /* IJSVGCommandClose.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandClose.m; sourceTree = "<group>"; };
|
||||
59E2642919BA240D008A6FDB /* IJSVGCommandCommandSmoothQuadraticCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandCommandSmoothQuadraticCurve.h; sourceTree = "<group>"; };
|
||||
59E2642A19BA240D008A6FDB /* IJSVGCommandCommandSmoothQuadraticCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandCommandSmoothQuadraticCurve.m; sourceTree = "<group>"; };
|
||||
59E2642B19BA240D008A6FDB /* IJSVGCommandCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandCurve.h; sourceTree = "<group>"; };
|
||||
59E2642C19BA240D008A6FDB /* IJSVGCommandCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandCurve.m; sourceTree = "<group>"; };
|
||||
59E2642D19BA240D008A6FDB /* IJSVGCommandHorizontalLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandHorizontalLine.h; sourceTree = "<group>"; };
|
||||
59E2642E19BA240D008A6FDB /* IJSVGCommandHorizontalLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandHorizontalLine.m; sourceTree = "<group>"; };
|
||||
59E2642F19BA240D008A6FDB /* IJSVGCommandLineTo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandLineTo.h; sourceTree = "<group>"; };
|
||||
59E2643019BA240D008A6FDB /* IJSVGCommandLineTo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandLineTo.m; sourceTree = "<group>"; };
|
||||
59E2643119BA240D008A6FDB /* IJSVGCommandMove.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandMove.h; sourceTree = "<group>"; };
|
||||
59E2643219BA240D008A6FDB /* IJSVGCommandMove.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandMove.m; sourceTree = "<group>"; };
|
||||
59E2643319BA240D008A6FDB /* IJSVGCommandQuadraticCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandQuadraticCurve.h; sourceTree = "<group>"; };
|
||||
59E2643419BA240D008A6FDB /* IJSVGCommandQuadraticCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandQuadraticCurve.m; sourceTree = "<group>"; };
|
||||
59E2643519BA240D008A6FDB /* IJSVGCommandSmoothCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandSmoothCurve.h; sourceTree = "<group>"; };
|
||||
59E2643619BA240D008A6FDB /* IJSVGCommandSmoothCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandSmoothCurve.m; sourceTree = "<group>"; };
|
||||
59E2643719BA240D008A6FDB /* IJSVGCommandVerticalLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandVerticalLine.h; sourceTree = "<group>"; };
|
||||
59E2643819BA240D008A6FDB /* IJSVGCommandVerticalLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandVerticalLine.m; sourceTree = "<group>"; };
|
||||
59E2643919BA240D008A6FDB /* IJSVGDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGDef.h; sourceTree = "<group>"; };
|
||||
59E2643A19BA240D008A6FDB /* IJSVGDef.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGDef.m; sourceTree = "<group>"; };
|
||||
59E2643B19BA240D008A6FDB /* IJSVGForeignObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGForeignObject.h; sourceTree = "<group>"; };
|
||||
59E2643C19BA240D008A6FDB /* IJSVGForeignObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGForeignObject.m; sourceTree = "<group>"; };
|
||||
59E2643D19BA240D008A6FDB /* IJSVGGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGradient.h; sourceTree = "<group>"; };
|
||||
59E2643E19BA240D008A6FDB /* IJSVGGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGradient.m; sourceTree = "<group>"; };
|
||||
59E2643F19BA240D008A6FDB /* IJSVGGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGroup.h; sourceTree = "<group>"; };
|
||||
59E2644019BA240D008A6FDB /* IJSVGGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGroup.m; sourceTree = "<group>"; };
|
||||
59E2644119BA240D008A6FDB /* IJSVGLinearGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGLinearGradient.h; sourceTree = "<group>"; };
|
||||
59E2644219BA240D008A6FDB /* IJSVGLinearGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGLinearGradient.m; sourceTree = "<group>"; };
|
||||
59E2644319BA240D008A6FDB /* IJSVGNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGNode.h; sourceTree = "<group>"; };
|
||||
59E2644419BA240D008A6FDB /* IJSVGNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGNode.m; sourceTree = "<group>"; };
|
||||
59E2644519BA240D008A6FDB /* IJSVGParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGParser.h; sourceTree = "<group>"; };
|
||||
59E2644619BA240D008A6FDB /* IJSVGParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGParser.m; sourceTree = "<group>"; };
|
||||
59E2644719BA240D008A6FDB /* IJSVGPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGPath.h; sourceTree = "<group>"; };
|
||||
59E2644819BA240D008A6FDB /* IJSVGPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGPath.m; sourceTree = "<group>"; };
|
||||
59E2644919BA240D008A6FDB /* IJSVGRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGRadialGradient.h; sourceTree = "<group>"; };
|
||||
59E2644A19BA240D008A6FDB /* IJSVGRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGRadialGradient.m; sourceTree = "<group>"; };
|
||||
59E2644B19BA240D008A6FDB /* IJSVGStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyle.h; sourceTree = "<group>"; };
|
||||
59E2644C19BA240D008A6FDB /* IJSVGStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyle.m; sourceTree = "<group>"; };
|
||||
59E2644D19BA240D008A6FDB /* IJSVGTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGTransform.h; sourceTree = "<group>"; };
|
||||
59E2644E19BA240D008A6FDB /* IJSVGTransform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGTransform.m; sourceTree = "<group>"; };
|
||||
59E2644F19BA240D008A6FDB /* IJSVGUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGUtils.h; sourceTree = "<group>"; };
|
||||
59E2645019BA240D008A6FDB /* IJSVGUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGUtils.m; sourceTree = "<group>"; };
|
||||
59E8ABE81E2102A30032A80C /* IJSVGPatternLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGPatternLayer.h; sourceTree = "<group>"; };
|
||||
59E8ABE91E2102A30032A80C /* IJSVGPatternLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGPatternLayer.m; sourceTree = "<group>"; };
|
||||
59E8ABEB1E211EBE0032A80C /* IJSVGLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGLayer.h; sourceTree = "<group>"; };
|
||||
59E8ABEC1E211EBE0032A80C /* IJSVGLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGLayer.m; sourceTree = "<group>"; };
|
||||
59E8ABEE1E211EDB0032A80C /* IJSVGShapeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGShapeLayer.h; sourceTree = "<group>"; };
|
||||
59E8ABEF1E211EDB0032A80C /* IJSVGShapeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGShapeLayer.m; sourceTree = "<group>"; };
|
||||
59E8ABF11E2167D90032A80C /* IJSVGImageLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGImageLayer.h; sourceTree = "<group>"; };
|
||||
59E8ABF21E2167D90032A80C /* IJSVGImageLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGImageLayer.m; sourceTree = "<group>"; };
|
||||
59E8ABF41E2176340032A80C /* IJSVGGroupLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGroupLayer.h; sourceTree = "<group>"; };
|
||||
59E8ABF51E2176340032A80C /* IJSVGGroupLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGroupLayer.m; sourceTree = "<group>"; };
|
||||
59E8ABF71E219C860032A80C /* IJSVGMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGMath.h; sourceTree = "<group>"; };
|
||||
59E8ABF81E219C860032A80C /* IJSVGMath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGMath.m; sourceTree = "<group>"; };
|
||||
59EA310E22CF395300DAB3B7 /* IJSVGImageRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGImageRep.h; sourceTree = "<group>"; };
|
||||
59EA310F22CF395400DAB3B7 /* IJSVGStringAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStringAdditions.m; sourceTree = "<group>"; };
|
||||
59EA311022CF395400DAB3B7 /* IJSVGRendering.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGRendering.m; sourceTree = "<group>"; };
|
||||
59EA311122CF395400DAB3B7 /* IJSVGRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGRendering.h; sourceTree = "<group>"; };
|
||||
59EA311222CF395400DAB3B7 /* IJSVGView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGView.h; sourceTree = "<group>"; };
|
||||
59EA311322CF395400DAB3B7 /* IJSVGImageRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGImageRep.m; sourceTree = "<group>"; };
|
||||
59EA311422CF395400DAB3B7 /* IJSVGView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGView.m; sourceTree = "<group>"; };
|
||||
59EA311522CF395400DAB3B7 /* IJSVGStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStringAdditions.h; sourceTree = "<group>"; };
|
||||
59F799E119B880CE00096CB7 /* htc_one.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = htc_one.svg; sourceTree = "<group>"; };
|
||||
59FB54B3280B038200D148FA /* IJSVG.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = IJSVG.xcodeproj; path = ../Framework/IJSVG/IJSVG.xcodeproj; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -269,6 +135,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
59FB54BE280B03E600D148FA /* IJSVG.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -285,9 +152,11 @@
|
||||
5956656E19B62F4600D805FF = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
59FB54B3280B038200D148FA /* IJSVG.xcodeproj */,
|
||||
5956657919B62F4600D805FF /* IJSVGExample */,
|
||||
5956658D19B62F4700D805FF /* IJSVGExampleTests */,
|
||||
5956657819B62F4600D805FF /* Products */,
|
||||
59FB54BD280B03E600D148FA /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -303,7 +172,7 @@
|
||||
5956657919B62F4600D805FF /* IJSVGExample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5956659B19B62FA400D805FF /* IJSVG */,
|
||||
5934D504280C933300BEF20F /* IJSVGExample.entitlements */,
|
||||
5956657E19B62F4600D805FF /* AppDelegate.h */,
|
||||
5956657F19B62F4600D805FF /* AppDelegate.m */,
|
||||
5956658119B62F4600D805FF /* Images.xcassets */,
|
||||
@@ -374,130 +243,19 @@
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5956659B19B62FA400D805FF /* IJSVG */ = {
|
||||
59FB54B4280B038200D148FA /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
59E2641A19BA240D008A6FDB /* source */,
|
||||
595665C619B6302600D805FF /* README.md */,
|
||||
59FB54B8280B038200D148FA /* IJSVG.framework */,
|
||||
);
|
||||
name = IJSVG;
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
59E2641A19BA240D008A6FDB /* source */ = {
|
||||
59FB54BD280B03E600D148FA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
59EA310E22CF395300DAB3B7 /* IJSVGImageRep.h */,
|
||||
59EA311322CF395400DAB3B7 /* IJSVGImageRep.m */,
|
||||
59EA311122CF395400DAB3B7 /* IJSVGRendering.h */,
|
||||
59EA311022CF395400DAB3B7 /* IJSVGRendering.m */,
|
||||
59EA311522CF395400DAB3B7 /* IJSVGStringAdditions.h */,
|
||||
59EA310F22CF395400DAB3B7 /* IJSVGStringAdditions.m */,
|
||||
59EA311222CF395400DAB3B7 /* IJSVGView.h */,
|
||||
59EA311422CF395400DAB3B7 /* IJSVGView.m */,
|
||||
59A3DA6B1E283022003E59A9 /* IJSVGTransaction.h */,
|
||||
59A3DA6C1E283022003E59A9 /* IJSVGTransaction.m */,
|
||||
598759F41E242C850024CC3F /* IJSVGExporterPathInstruction.h */,
|
||||
598759F51E242C850024CC3F /* IJSVGExporterPathInstruction.m */,
|
||||
5941DAF91CF9BC9B00B3A911 /* IJSVGImage.h */,
|
||||
5941DAFA1CF9BC9B00B3A911 /* IJSVGImage.m */,
|
||||
5941DAFB1CF9BC9B00B3A911 /* IJSVGPattern.h */,
|
||||
5941DAFC1CF9BC9B00B3A911 /* IJSVGPattern.m */,
|
||||
599465D41C4AA87200A2EEF3 /* IJSVGStyleSheet.h */,
|
||||
599465D51C4AA87200A2EEF3 /* IJSVGStyleSheet.m */,
|
||||
599465D61C4AA87200A2EEF3 /* IJSVGStyleSheetRule.h */,
|
||||
599465D71C4AA87200A2EEF3 /* IJSVGStyleSheetRule.m */,
|
||||
599465D81C4AA87200A2EEF3 /* IJSVGStyleSheetSelector.h */,
|
||||
599465D91C4AA87200A2EEF3 /* IJSVGStyleSheetSelector.m */,
|
||||
599465DA1C4AA87200A2EEF3 /* IJSVGStyleSheetSelectorRaw.h */,
|
||||
599465DB1C4AA87200A2EEF3 /* IJSVGStyleSheetSelectorRaw.m */,
|
||||
5948DED01BB2BFE5004156FF /* IJSVGError.h */,
|
||||
5948DED11BB2BFE5004156FF /* IJSVGFontConverter.h */,
|
||||
5948DED21BB2BFE5004156FF /* IJSVGFontConverter.m */,
|
||||
5948DED31BB2BFE5004156FF /* IJSVGWriter.h */,
|
||||
5948DED41BB2BFE5004156FF /* IJSVGWriter.m */,
|
||||
59E2641B19BA240D008A6FDB /* IJSVG.h */,
|
||||
59E2641C19BA240D008A6FDB /* IJSVG.m */,
|
||||
59E2641D19BA240D008A6FDB /* IJSVGBezierPathAdditions.h */,
|
||||
59E2641E19BA240D008A6FDB /* IJSVGBezierPathAdditions.m */,
|
||||
59E2641F19BA240D008A6FDB /* IJSVGCache.h */,
|
||||
59E2642019BA240D008A6FDB /* IJSVGCache.m */,
|
||||
59E2642119BA240D008A6FDB /* IJSVGColor.h */,
|
||||
59E2642219BA240D008A6FDB /* IJSVGColor.m */,
|
||||
59E2642319BA240D008A6FDB /* IJSVGCommand.h */,
|
||||
59E2642419BA240D008A6FDB /* IJSVGCommand.m */,
|
||||
59E2642519BA240D008A6FDB /* IJSVGCommandArc.h */,
|
||||
59E2642619BA240D008A6FDB /* IJSVGCommandArc.m */,
|
||||
59E2642719BA240D008A6FDB /* IJSVGCommandClose.h */,
|
||||
59E2642819BA240D008A6FDB /* IJSVGCommandClose.m */,
|
||||
59E2642919BA240D008A6FDB /* IJSVGCommandCommandSmoothQuadraticCurve.h */,
|
||||
59E2642A19BA240D008A6FDB /* IJSVGCommandCommandSmoothQuadraticCurve.m */,
|
||||
59E2642B19BA240D008A6FDB /* IJSVGCommandCurve.h */,
|
||||
59E2642C19BA240D008A6FDB /* IJSVGCommandCurve.m */,
|
||||
59E2642D19BA240D008A6FDB /* IJSVGCommandHorizontalLine.h */,
|
||||
59E2642E19BA240D008A6FDB /* IJSVGCommandHorizontalLine.m */,
|
||||
59E2642F19BA240D008A6FDB /* IJSVGCommandLineTo.h */,
|
||||
59E2643019BA240D008A6FDB /* IJSVGCommandLineTo.m */,
|
||||
59E2643119BA240D008A6FDB /* IJSVGCommandMove.h */,
|
||||
59E2643219BA240D008A6FDB /* IJSVGCommandMove.m */,
|
||||
59E2643319BA240D008A6FDB /* IJSVGCommandQuadraticCurve.h */,
|
||||
59E2643419BA240D008A6FDB /* IJSVGCommandQuadraticCurve.m */,
|
||||
59E2643519BA240D008A6FDB /* IJSVGCommandSmoothCurve.h */,
|
||||
59E2643619BA240D008A6FDB /* IJSVGCommandSmoothCurve.m */,
|
||||
59E2643719BA240D008A6FDB /* IJSVGCommandVerticalLine.h */,
|
||||
59E2643819BA240D008A6FDB /* IJSVGCommandVerticalLine.m */,
|
||||
59E2643919BA240D008A6FDB /* IJSVGDef.h */,
|
||||
59E2643A19BA240D008A6FDB /* IJSVGDef.m */,
|
||||
59E2643B19BA240D008A6FDB /* IJSVGForeignObject.h */,
|
||||
59E2643C19BA240D008A6FDB /* IJSVGForeignObject.m */,
|
||||
59E2643D19BA240D008A6FDB /* IJSVGGradient.h */,
|
||||
59E2643E19BA240D008A6FDB /* IJSVGGradient.m */,
|
||||
343A19161FB2212C000652A2 /* IJSVGGradientUnitLength.h */,
|
||||
343A19171FB2212C000652A2 /* IJSVGGradientUnitLength.m */,
|
||||
59E2643F19BA240D008A6FDB /* IJSVGGroup.h */,
|
||||
59E2644019BA240D008A6FDB /* IJSVGGroup.m */,
|
||||
59E2644119BA240D008A6FDB /* IJSVGLinearGradient.h */,
|
||||
59E2644219BA240D008A6FDB /* IJSVGLinearGradient.m */,
|
||||
59E2644319BA240D008A6FDB /* IJSVGNode.h */,
|
||||
59E2644419BA240D008A6FDB /* IJSVGNode.m */,
|
||||
59E2644519BA240D008A6FDB /* IJSVGParser.h */,
|
||||
59E2644619BA240D008A6FDB /* IJSVGParser.m */,
|
||||
59E2644719BA240D008A6FDB /* IJSVGPath.h */,
|
||||
59E2644819BA240D008A6FDB /* IJSVGPath.m */,
|
||||
59E2644919BA240D008A6FDB /* IJSVGRadialGradient.h */,
|
||||
59E2644A19BA240D008A6FDB /* IJSVGRadialGradient.m */,
|
||||
59E2644B19BA240D008A6FDB /* IJSVGStyle.h */,
|
||||
59E2644C19BA240D008A6FDB /* IJSVGStyle.m */,
|
||||
59E2644D19BA240D008A6FDB /* IJSVGTransform.h */,
|
||||
59E2644E19BA240D008A6FDB /* IJSVGTransform.m */,
|
||||
59E2644F19BA240D008A6FDB /* IJSVGUtils.h */,
|
||||
59E2645019BA240D008A6FDB /* IJSVGUtils.m */,
|
||||
592840AF1E153F3D002F9AF0 /* IJSVGLayerTree.h */,
|
||||
592840B01E153F3D002F9AF0 /* IJSVGLayerTree.m */,
|
||||
592840B21E155308002F9AF0 /* IJSVGGradientLayer.h */,
|
||||
592840B31E155308002F9AF0 /* IJSVGGradientLayer.m */,
|
||||
591A13DF1E19838F001D1629 /* IJSVGText.h */,
|
||||
591A13E01E19838F001D1629 /* IJSVGText.m */,
|
||||
591704CA1E2016E400012644 /* IJSVGExporter.h */,
|
||||
591704CB1E2016E400012644 /* IJSVGExporter.m */,
|
||||
59E8ABE81E2102A30032A80C /* IJSVGPatternLayer.h */,
|
||||
59E8ABE91E2102A30032A80C /* IJSVGPatternLayer.m */,
|
||||
59E8ABEB1E211EBE0032A80C /* IJSVGLayer.h */,
|
||||
59E8ABEC1E211EBE0032A80C /* IJSVGLayer.m */,
|
||||
59E8ABEE1E211EDB0032A80C /* IJSVGShapeLayer.h */,
|
||||
59E8ABEF1E211EDB0032A80C /* IJSVGShapeLayer.m */,
|
||||
59E8ABF11E2167D90032A80C /* IJSVGImageLayer.h */,
|
||||
59E8ABF21E2167D90032A80C /* IJSVGImageLayer.m */,
|
||||
59E8ABF41E2176340032A80C /* IJSVGGroupLayer.h */,
|
||||
59E8ABF51E2176340032A80C /* IJSVGGroupLayer.m */,
|
||||
59E8ABF71E219C860032A80C /* IJSVGMath.h */,
|
||||
59E8ABF81E219C860032A80C /* IJSVGMath.m */,
|
||||
597046A01E24352700A60138 /* IJSVGStrokeLayer.h */,
|
||||
597046A11E24352700A60138 /* IJSVGStrokeLayer.m */,
|
||||
59E0F5EB1E29964700F757F7 /* IJSVGUnitLength.h */,
|
||||
59E0F5EC1E29964700F757F7 /* IJSVGUnitLength.m */,
|
||||
);
|
||||
name = source;
|
||||
path = ../../source;
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
@@ -510,10 +268,12 @@
|
||||
5956657319B62F4600D805FF /* Sources */,
|
||||
5956657419B62F4600D805FF /* Frameworks */,
|
||||
5956657519B62F4600D805FF /* Resources */,
|
||||
59FB54BF280B03EE00D148FA /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
59FB54BC280B03E100D148FA /* PBXTargetDependency */,
|
||||
);
|
||||
name = IJSVGExample;
|
||||
productName = IJSVGExample;
|
||||
@@ -568,6 +328,12 @@
|
||||
mainGroup = 5956656E19B62F4600D805FF;
|
||||
productRefGroup = 5956657819B62F4600D805FF /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 59FB54B4280B038200D148FA /* Products */;
|
||||
ProjectRef = 59FB54B3280B038200D148FA /* IJSVG.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
5956657619B62F4600D805FF /* IJSVGExample */,
|
||||
@@ -576,6 +342,16 @@
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
59FB54B8280B038200D148FA /* IJSVG.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
path = IJSVG.framework;
|
||||
remoteRef = 59FB54B7280B038200D148FA /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
5956657519B62F4600D805FF /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
@@ -620,70 +396,15 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
59E2645419BA240D008A6FDB /* IJSVGColor.m in Sources */,
|
||||
59E2646919BA240D008A6FDB /* IJSVGStyle.m in Sources */,
|
||||
59E2646419BA240D008A6FDB /* IJSVGLinearGradient.m in Sources */,
|
||||
595665DC19B6302600D805FF /* README.md in Sources */,
|
||||
59EA311922CF395400DAB3B7 /* IJSVGView.m in Sources */,
|
||||
5941DAFD1CF9BC9B00B3A911 /* IJSVGImage.m in Sources */,
|
||||
599465DE1C4AA87200A2EEF3 /* IJSVGStyleSheetSelector.m in Sources */,
|
||||
5948DED61BB2BFE5004156FF /* IJSVGWriter.m in Sources */,
|
||||
599465DD1C4AA87200A2EEF3 /* IJSVGStyleSheetRule.m in Sources */,
|
||||
5986308A19BA106D00CF15EA /* SVGExampleView5.m in Sources */,
|
||||
59E2645619BA240D008A6FDB /* IJSVGCommandArc.m in Sources */,
|
||||
59E8ABF91E219C860032A80C /* IJSVGMath.m in Sources */,
|
||||
343A19181FB2212C000652A2 /* IJSVGGradientUnitLength.m in Sources */,
|
||||
59265CEB1C4F843E00F333F0 /* SVGExampleView6.m in Sources */,
|
||||
5941DAFE1CF9BC9B00B3A911 /* IJSVGPattern.m in Sources */,
|
||||
59E8ABF01E211EDB0032A80C /* IJSVGShapeLayer.m in Sources */,
|
||||
599465DC1C4AA87200A2EEF3 /* IJSVGStyleSheet.m in Sources */,
|
||||
59E2645319BA240D008A6FDB /* IJSVGCache.m in Sources */,
|
||||
599465DF1C4AA87200A2EEF3 /* IJSVGStyleSheetSelectorRaw.m in Sources */,
|
||||
59E8ABEA1E2102A30032A80C /* IJSVGPatternLayer.m in Sources */,
|
||||
59E2646619BA240D008A6FDB /* IJSVGParser.m in Sources */,
|
||||
595665E119B630B600D805FF /* SVGView.m in Sources */,
|
||||
59E2645719BA240D008A6FDB /* IJSVGCommandClose.m in Sources */,
|
||||
59E2645A19BA240D008A6FDB /* IJSVGCommandHorizontalLine.m in Sources */,
|
||||
59E2645B19BA240D008A6FDB /* IJSVGCommandLineTo.m in Sources */,
|
||||
59E2645F19BA240D008A6FDB /* IJSVGCommandVerticalLine.m in Sources */,
|
||||
59E8ABF61E2176340032A80C /* IJSVGGroupLayer.m in Sources */,
|
||||
59E2646819BA240D008A6FDB /* IJSVGRadialGradient.m in Sources */,
|
||||
59E8ABF31E2167D90032A80C /* IJSVGImageLayer.m in Sources */,
|
||||
59E2645919BA240D008A6FDB /* IJSVGCommandCurve.m in Sources */,
|
||||
5956658019B62F4600D805FF /* AppDelegate.m in Sources */,
|
||||
59E2646519BA240D008A6FDB /* IJSVGNode.m in Sources */,
|
||||
591A13E11E19838F001D1629 /* IJSVGText.m in Sources */,
|
||||
59EA311822CF395400DAB3B7 /* IJSVGImageRep.m in Sources */,
|
||||
59A11E6C19B89CEA00E44498 /* SVGExampleView1.m in Sources */,
|
||||
59A3DA6D1E283022003E59A9 /* IJSVGTransaction.m in Sources */,
|
||||
59E2646A19BA240D008A6FDB /* IJSVGTransform.m in Sources */,
|
||||
59E2646B19BA240D008A6FDB /* IJSVGUtils.m in Sources */,
|
||||
592840B41E155308002F9AF0 /* IJSVGGradientLayer.m in Sources */,
|
||||
59E2646019BA240D008A6FDB /* IJSVGDef.m in Sources */,
|
||||
59E2645C19BA240D008A6FDB /* IJSVGCommandMove.m in Sources */,
|
||||
59E2646219BA240D008A6FDB /* IJSVGGradient.m in Sources */,
|
||||
598759F61E242C850024CC3F /* IJSVGExporterPathInstruction.m in Sources */,
|
||||
59E2645E19BA240D008A6FDB /* IJSVGCommandSmoothCurve.m in Sources */,
|
||||
59E2645819BA240D008A6FDB /* IJSVGCommandCommandSmoothQuadraticCurve.m in Sources */,
|
||||
59EA311622CF395400DAB3B7 /* IJSVGStringAdditions.m in Sources */,
|
||||
59E2645D19BA240D008A6FDB /* IJSVGCommandQuadraticCurve.m in Sources */,
|
||||
59E2646719BA240D008A6FDB /* IJSVGPath.m in Sources */,
|
||||
59E8ABED1E211EBE0032A80C /* IJSVGLayer.m in Sources */,
|
||||
591704CC1E2016E400012644 /* IJSVGExporter.m in Sources */,
|
||||
59E2645519BA240D008A6FDB /* IJSVGCommand.m in Sources */,
|
||||
59A11E7219B89D6600E44498 /* SVGExampleView3.m in Sources */,
|
||||
59E0F5ED1E29964700F757F7 /* IJSVGUnitLength.m in Sources */,
|
||||
5956657D19B62F4600D805FF /* main.m in Sources */,
|
||||
59EA311722CF395400DAB3B7 /* IJSVGRendering.m in Sources */,
|
||||
59A11E6F19B89D2000E44498 /* SVGExampleView2.m in Sources */,
|
||||
5948DED51BB2BFE5004156FF /* IJSVGFontConverter.m in Sources */,
|
||||
59E2646319BA240D008A6FDB /* IJSVGGroup.m in Sources */,
|
||||
59459CEF19B9074F00CE493B /* SVGExampleView4.m in Sources */,
|
||||
597046A21E24352700A60138 /* IJSVGStrokeLayer.m in Sources */,
|
||||
59E2646119BA240D008A6FDB /* IJSVGForeignObject.m in Sources */,
|
||||
59E2645219BA240D008A6FDB /* IJSVGBezierPathAdditions.m in Sources */,
|
||||
59E2645119BA240D008A6FDB /* IJSVG.m in Sources */,
|
||||
592840B11E153F3D002F9AF0 /* IJSVGLayerTree.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -703,6 +424,11 @@
|
||||
target = 5956657619B62F4600D805FF /* IJSVGExample */;
|
||||
targetProxy = 5956658B19B62F4700D805FF /* PBXContainerItemProxy */;
|
||||
};
|
||||
59FB54BC280B03E100D148FA /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = IJSVG;
|
||||
targetProxy = 59FB54BB280B03E100D148FA /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
@@ -799,6 +525,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = IJSVGExample/IJSVGExample.entitlements;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
INFOPLIST_FILE = IJSVGExample/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
@@ -810,6 +537,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = IJSVGExample/IJSVGExample.entitlements;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
INFOPLIST_FILE = IJSVGExample/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
|
||||
BIN
Binary file not shown.
+34
@@ -3,4 +3,38 @@
|
||||
uuid = "21141E92-29FD-4CF6-AB04-0D4E4FD9A4AC"
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "4737255E-8CA5-4D4C-87C9-0625C969F154"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "../Framework/IJSVG/IJSVG/Source/Layers/IJSVGGradientLayer.m"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "102"
|
||||
endingLineNumber = "102"
|
||||
landmarkName = "-drawInContext:"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "22FC47C6-0C8B-4BF3-95A6-4AF1D5B32C95"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "../Framework/IJSVG/IJSVG/Source/Layers/IJSVGLayer.m"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "200"
|
||||
endingLineNumber = "200"
|
||||
landmarkName = "+clipContextWithMask:toLayer:inContext:drawingBlock:"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
|
||||
+16
-15
@@ -40,8 +40,16 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "5956657619B62F4600D805FF"
|
||||
BuildableName = "IJSVGExample.app"
|
||||
BlueprintName = "IJSVGExample"
|
||||
ReferencedContainer = "container:IJSVGExample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@@ -54,23 +62,11 @@
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "5956657619B62F4600D805FF"
|
||||
BuildableName = "IJSVGExample.app"
|
||||
BlueprintName = "IJSVGExample"
|
||||
ReferencedContainer = "container:IJSVGExample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
@@ -87,8 +83,13 @@
|
||||
ReferencedContainer = "container:IJSVGExample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = "CG_CONTEXT_SHOW_BACKTRACE"
|
||||
value = "1"
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 515 KiB After Width: | Height: | Size: 89 KiB |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -24,6 +24,8 @@
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014 Curtis Hard. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "IJSVG.h"
|
||||
#import <IJSVG/IJSVG.h>
|
||||
|
||||
@interface SVGView : NSView {
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
//
|
||||
|
||||
#import "SVGView.h"
|
||||
#import "IJSVGExporter.h"
|
||||
|
||||
@implementation SVGView
|
||||
|
||||
@@ -21,8 +20,8 @@
|
||||
{
|
||||
if( ( self = [super initWithFrame:frameRect] ) != nil )
|
||||
{
|
||||
svg = [self svg];
|
||||
svg.renderQuality = IJSVGRenderQualityFullResolution;
|
||||
svg = [self svg].retain;
|
||||
svg.renderQuality = kIJSVGRenderQualityFullResolution;
|
||||
svg.renderingBackingScaleHelper = ^{
|
||||
return self.window.backingScaleFactor;
|
||||
};
|
||||
@@ -32,7 +31,7 @@
|
||||
|
||||
- (IJSVG *)svg
|
||||
{
|
||||
return [IJSVG svgNamed:@"test (1)"];
|
||||
return [IJSVG svgNamed:@"AJ_Digital_Camera"];
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
|
||||
+19
-7415
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 522 KiB After Width: | Height: | Size: 992 B |
Reference in New Issue
Block a user