Compare commits

..

35 Commits

Author SHA1 Message Date
Curtis Hard 050df84672 Adds isNoneOrTransparent to COlor 2022-04-19 18:11:02 +01:00
Curtis Hard ac61d3d6d6 Adds image generation to IJSVGLayer 2022-04-18 17:32:20 +01:00
Curtis Hard fdde1fd5f6 Fixes transforms and masking 2022-04-18 14:45:24 +01:00
Curtis Hard fe179076cc More fixes 2022-04-18 11:45:04 +01:00
Curtis Hard 01dd0d25d2 Make sure the node actually exists 2022-04-17 17:57:52 +01:00
Curtis Hard 799593d7d8 Removed log 2022-04-17 17:57:09 +01:00
Curtis Hard 0c7cfd776c Fixes stylesheets 2022-04-17 17:57:01 +01:00
Curtis Hard 757c4317d3 Adds better rendering calls into SVG 2022-04-17 12:45:44 +01:00
Curtis Hard 1727505968 Removed IJSVG_DRAWABLE_LAYER 2022-04-17 11:58:49 +01:00
Curtis Hard 775c28e91a Updated example and added better support for ratios 2022-04-16 17:50:57 +01:00
Curtis Hard ec539a12b3 More alignment stuff 2022-04-16 13:51:33 +01:00
Curtis Hard 43210c018e Fixes strokes with layer of constant fill color
- started to out viewboxes
2022-04-15 21:10:48 +01:00
Curtis Hard 3773e10f44 Fixes strokes, some patterns, changes how we parse commands ready for units 2022-04-13 21:20:53 +01:00
Curtis Hard 51fb9cc871 added referencing layers into layer tree 2022-04-12 20:00:58 +01:00
Curtis Hard be08ada5da Fixes gradients 2022-04-11 10:14:08 +01:00
Curtis Hard a3a6ee5a05 Fixes absolute transform and gradients 2022-04-08 21:56:03 +01:00
Curtis Hard cccfc0db68 Various fixes 2022-04-07 15:36:33 +01:00
Curtis Hard 19db898bdd More gradient things that dont work 2022-04-03 20:05:58 +01:00
Curtis Hard 8abbdf390a Continue of refactor 2022-04-02 13:51:47 +01:00
Curtis Hard 6e98e2cfed Removes useless properties 2022-03-31 13:36:53 +01:00
Curtis Hard 2c536a8962 Adds .children and improvements to addChild/removeChild 2022-03-30 19:52:30 +01:00
Curtis Hard 65a8c0a691 Proper clip path 2022-03-30 15:26:32 +01:00
Curtis Hard 2942cc0a58 Added IJSVGColorNode and traits 2022-03-29 20:12:53 +01:00
Curtis Hard ba7a05553e Adds frame calculations onto group 2022-03-29 11:37:28 +01:00
Curtis Hard c9a7788d98 Added correctly nested detached nodes 2022-03-29 09:34:08 +01:00
Curtis Hard 774ff48074 Refactor, IJSVGParser is not the root anymore, there is a new IJSVGRootNode as the root of the node tree 2022-03-28 20:31:27 +01:00
Curtis Hard 2eb629cd21 Overhaul of parser 2022-03-28 19:14:46 +01:00
Curtis Hard 137e34623f hacky things! 2022-03-27 22:05:19 +01:00
Curtis Hard 39b0b5bbb4 More image fixes 2022-03-27 20:45:31 +01:00
Curtis Hard 820fca2679 Merge branch 'features/patterns' of https://github.com/curthard89/IJSVG into features/patterns 2022-03-27 15:38:09 +01:00
Curtis Hard 2e5819183d More pattern things 2022-03-27 15:36:33 +01:00
Curtis Hard eff56d3c60 More pattern things, this is not fun 2022-03-27 15:35:51 +01:00
Curtis Hard 7a4fd35a64 initial pattern fixes 2022-03-25 13:21:59 +00:00
Curtis Hard 964dc3005d Merge branch 'fixes/const-memory-alloc-issues' of https://github.com/curthard89/IJSVG 2022-03-23 18:27:54 +00:00
Curtis Hard 1a8d44ec95 Fixes masking for gradients 2022-03-23 18:27:41 +00:00
85 changed files with 4147 additions and 17624 deletions
+1
View File
@@ -0,0 +1 @@
.DS_Store
@@ -7,6 +7,8 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* 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, ); }; }; 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 */; }; 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, ); }; }; 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 */; }; 594CF55F238FF462009B251B /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF55E238FF462009B251B /* AppKit.framework */; };
594CF561238FF46C009B251B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF560238FF46C009B251B /* Foundation.framework */; }; 594CF561238FF46C009B251B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF560238FF46C009B251B /* Foundation.framework */; };
594CF563238FF473009B251B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF562238FF473009B251B /* QuartzCore.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 */; }; 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, ); }; }; 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 */; }; 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 */; }; 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, ); }; }; 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 */; }; 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 */ /* End PBXBuildFile section */
/* Begin PBXFileReference 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>"; }; 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>"; }; 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>"; }; 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; }; 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; }; 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; }; 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; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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 */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@@ -355,6 +375,10 @@
59EB757A23905F6C00F5AE63 /* IJSVGShapeLayer.m */, 59EB757A23905F6C00F5AE63 /* IJSVGShapeLayer.m */,
59EB75A423905F6E00F5AE63 /* IJSVGStrokeLayer.h */, 59EB75A423905F6E00F5AE63 /* IJSVGStrokeLayer.h */,
59EB757423905F6C00F5AE63 /* IJSVGStrokeLayer.m */, 59EB757423905F6C00F5AE63 /* IJSVGStrokeLayer.m */,
590EB7A227F637EF0047CECF /* IJSVGTransformLayer.h */,
590EB7A327F637EF0047CECF /* IJSVGTransformLayer.m */,
5978C468280A241200D25296 /* IJSVGRootLayer.h */,
5978C469280A241200D25296 /* IJSVGRootLayer.m */,
); );
path = Layers; path = Layers;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -395,6 +419,10 @@
59EB75AA23905F6F00F5AE63 /* IJSVGPattern.m */, 59EB75AA23905F6F00F5AE63 /* IJSVGPattern.m */,
59EB756B23905F6B00F5AE63 /* IJSVGText.h */, 59EB756B23905F6B00F5AE63 /* IJSVGText.h */,
59EB75C023905F7100F5AE63 /* IJSVGText.m */, 59EB75C023905F7100F5AE63 /* IJSVGText.m */,
59FCC09227F2394D00BB924E /* IJSVGRootNode.h */,
59FCC09327F2394D00BB924E /* IJSVGRootNode.m */,
59FDBEFE27F3454800AF7038 /* IJSVGColorNode.h */,
59FDBEFF27F3454800AF7038 /* IJSVGColorNode.m */,
); );
path = Nodes; path = Nodes;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -422,6 +450,8 @@
59A24EBB23F480EA0090C374 /* IJSVGUnitSize.m */, 59A24EBB23F480EA0090C374 /* IJSVGUnitSize.m */,
591A3E4B25CC91F800AD45B7 /* IJSVGParsing.h */, 591A3E4B25CC91F800AD45B7 /* IJSVGParsing.h */,
591A3E4C25CC91F800AD45B7 /* IJSVGParsing.m */, 591A3E4C25CC91F800AD45B7 /* IJSVGParsing.m */,
59F9EAF62808BB5F00188ACB /* IJSVGViewBox.h */,
59F9EAF72808BB5F00188ACB /* IJSVGViewBox.m */,
); );
path = Utils; path = Utils;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -597,8 +627,13 @@
59E7CFAF23B148600077D599 /* IJSVGCommandParser.h in Headers */, 59E7CFAF23B148600077D599 /* IJSVGCommandParser.h in Headers */,
59EB762823905F7300F5AE63 /* IJSVGCommandClose.h in Headers */, 59EB762823905F7300F5AE63 /* IJSVGCommandClose.h in Headers */,
59EB75E423905F7300F5AE63 /* IJSVGGradientUnitLength.h in Headers */, 59EB75E423905F7300F5AE63 /* IJSVGGradientUnitLength.h in Headers */,
59FCC09427F2394D00BB924E /* IJSVGRootNode.h in Headers */,
594A10DA248D7C90001A3181 /* NSImage+IJSVGAdditions.h in Headers */, 594A10DA248D7C90001A3181 /* NSImage+IJSVGAdditions.h in Headers */,
59EB762D23905F7300F5AE63 /* IJSVGLayerTree.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 */, 59EB760B23905F7300F5AE63 /* IJSVGStyleSheetSelector.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -696,6 +731,7 @@
59EB760723905F7300F5AE63 /* IJSVGNode.m in Sources */, 59EB760723905F7300F5AE63 /* IJSVGNode.m in Sources */,
5919E65C23F480330051873A /* IJSVGUnitPoint.m in Sources */, 5919E65C23F480330051873A /* IJSVGUnitPoint.m in Sources */,
59EB75E923905F7300F5AE63 /* IJSVGStringAdditions.m in Sources */, 59EB75E923905F7300F5AE63 /* IJSVGStringAdditions.m in Sources */,
59FDBF0127F3454800AF7038 /* IJSVGColorNode.m in Sources */,
59EB761723905F7300F5AE63 /* IJSVGRadialGradient.m in Sources */, 59EB761723905F7300F5AE63 /* IJSVGRadialGradient.m in Sources */,
59EB75E223905F7300F5AE63 /* IJSVGColorList.m in Sources */, 59EB75E223905F7300F5AE63 /* IJSVGColorList.m in Sources */,
59EB75ED23905F7300F5AE63 /* IJSVGFontConverter.m in Sources */, 59EB75ED23905F7300F5AE63 /* IJSVGFontConverter.m in Sources */,
@@ -707,6 +743,7 @@
59EB75F323905F7300F5AE63 /* IJSVGGroupLayer.m in Sources */, 59EB75F323905F7300F5AE63 /* IJSVGGroupLayer.m in Sources */,
591A3E4E25CC91F800AD45B7 /* IJSVGParsing.m in Sources */, 591A3E4E25CC91F800AD45B7 /* IJSVGParsing.m in Sources */,
5919E65823F47FF60051873A /* IJSVGUnitRect.m in Sources */, 5919E65823F47FF60051873A /* IJSVGUnitRect.m in Sources */,
5978C46B280A241200D25296 /* IJSVGRootLayer.m in Sources */,
59EB762523905F7300F5AE63 /* IJSVGTransform.m in Sources */, 59EB762523905F7300F5AE63 /* IJSVGTransform.m in Sources */,
59EB760023905F7300F5AE63 /* IJSVGGradientLayer.m in Sources */, 59EB760023905F7300F5AE63 /* IJSVGGradientLayer.m in Sources */,
59EB762B23905F7300F5AE63 /* IJSVGUnitLength.m in Sources */, 59EB762B23905F7300F5AE63 /* IJSVGUnitLength.m in Sources */,
@@ -718,14 +755,17 @@
59EB762423905F7300F5AE63 /* IJSVGTransaction.m in Sources */, 59EB762423905F7300F5AE63 /* IJSVGTransaction.m in Sources */,
59EB75DA23905F7300F5AE63 /* IJSVGDef.m in Sources */, 59EB75DA23905F7300F5AE63 /* IJSVGDef.m in Sources */,
59EB763723905F7300F5AE63 /* IJSVGCommandClose.m in Sources */, 59EB763723905F7300F5AE63 /* IJSVGCommandClose.m in Sources */,
59F9EAF92808BB5F00188ACB /* IJSVGViewBox.m in Sources */,
59EB764323905F7300F5AE63 /* IJSVGGradient.m in Sources */, 59EB764323905F7300F5AE63 /* IJSVGGradient.m in Sources */,
59EB762A23905F7300F5AE63 /* IJSVGGradientUnitLength.m in Sources */, 59EB762A23905F7300F5AE63 /* IJSVGGradientUnitLength.m in Sources */,
59EB764223905F7300F5AE63 /* IJSVGStyleSheet.m in Sources */, 59EB764223905F7300F5AE63 /* IJSVGStyleSheet.m in Sources */,
59EB764023905F7300F5AE63 /* IJSVGExporterPathInstruction.m in Sources */, 59EB764023905F7300F5AE63 /* IJSVGExporterPathInstruction.m in Sources */,
59EB75FE23905F7300F5AE63 /* IJSVGRenderingStyle.m in Sources */, 59EB75FE23905F7300F5AE63 /* IJSVGRenderingStyle.m in Sources */,
59EB75F223905F7300F5AE63 /* IJSVGStyleSheetSelectorRaw.m in Sources */, 59EB75F223905F7300F5AE63 /* IJSVGStyleSheetSelectorRaw.m in Sources */,
590EB7A527F637EF0047CECF /* IJSVGTransformLayer.m in Sources */,
59EB75EE23905F7300F5AE63 /* IJSVGImageRep.m in Sources */, 59EB75EE23905F7300F5AE63 /* IJSVGImageRep.m in Sources */,
59EB762223905F7300F5AE63 /* IJSVGMath.m in Sources */, 59EB762223905F7300F5AE63 /* IJSVGMath.m in Sources */,
59FCC09527F2394D00BB924E /* IJSVGRootNode.m in Sources */,
59EB763D23905F7300F5AE63 /* IJSVGGroup.m in Sources */, 59EB763D23905F7300F5AE63 /* IJSVGGroup.m in Sources */,
59EB761F23905F7300F5AE63 /* IJSVGCommandLineTo.m in Sources */, 59EB761F23905F7300F5AE63 /* IJSVGCommandLineTo.m in Sources */,
59EB75F123905F7300F5AE63 /* IJSVGUtils.m in Sources */, 59EB75F123905F7300F5AE63 /* IJSVGUtils.m in Sources */,
@@ -181,6 +181,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
+ (NSString*)colorStringFromColor:(NSColor*)color; + (NSString*)colorStringFromColor:(NSColor*)color;
+ (NSColor*)colorFromHEXInteger:(NSInteger)hex; + (NSColor*)colorFromHEXInteger:(NSInteger)hex;
+ (NSColor*)computeColor:(id)colour; + (NSColor*)computeColor:(id)colour;
+ (BOOL)isNoneOrTransparent:(NSString*)string;
+ (NSColor*)colorFromString:(NSString*)string; + (NSColor*)colorFromString:(NSString*)string;
+ (NSColor*)colorFromHEXString:(NSString*)string; + (NSColor*)colorFromHEXString:(NSString*)string;
+ (NSColor*)colorFromHEXString:(NSString*)string + (NSColor*)colorFromHEXString:(NSString*)string
@@ -244,6 +244,12 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
alpha:a]]; 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 + (NSColor*)colorFromString:(NSString*)string
{ {
// swap over to C for performance // swap over to C for performance
@@ -327,7 +333,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
if (strcmp(str, "none") == 0 || if (strcmp(str, "none") == 0 ||
strcmp(str, "transparent") == 0) { strcmp(str, "transparent") == 0) {
(void)free(str), str = NULL; (void)free(str), str = NULL;
return [self computeColorSpace:NSColor.clearColor]; return nil;
} }
// could return nil // could return nil
@@ -17,12 +17,11 @@ typedef NS_ENUM(NSInteger, IJSVGCommandType) {
kIJSVGCommandTypeRelative kIJSVGCommandTypeRelative
}; };
@interface IJSVGCommand : NSObject { @interface IJSVGCommand : NSObject <NSCopying> {
@private @private
NSInteger _currentIndex; NSInteger _currentIndex;
} }
@property (nonatomic, copy) NSString* commandString;
@property (nonatomic, assign) char command; @property (nonatomic, assign) char command;
@property (nonatomic, assign) CGFloat* parameters; @property (nonatomic, assign) CGFloat* parameters;
@property (nonatomic, assign) NSInteger parameterCount; @property (nonatomic, assign) NSInteger parameterCount;
@@ -41,17 +40,30 @@ typedef NS_ENUM(NSInteger, IJSVGCommandType) {
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type type:(IJSVGCommandType)type
path:(IJSVGPath*)path; path:(CGMutablePathRef)path;
+ (void)parseParams:(CGFloat*)params + (void)parseParams:(CGFloat*)params
paramCount:(NSInteger)paramCount paramCount:(NSInteger)paramCount
intoArray:(NSMutableArray<IJSVGCommand*>*)commands intoArray:(NSMutableArray<IJSVGCommand*>*)commands
parentCommand:(IJSVGCommand*)parentCommand; 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 - (id)initWithCommandStringBuffer:(const char*)str
dataStream:(IJSVGPathDataStream*)dataStream; dataStream:(IJSVGPathDataStream*)dataStream;
- (IJSVGCommand*)subcommandWithParameters:(CGFloat*)subParams - (IJSVGCommand*)subcommandWithParameters:(CGFloat*)subParams
paramCount:(NSInteger)paramCount paramCount:(NSInteger)paramCount
previousCommand:(IJSVGCommand*)command; previousCommand:(IJSVGCommand*)command;
- (void)convertToUnits:(IJSVGUnitType)units
boundingBox:(CGRect)boundingBox;
- (IJSVGCommand*)commandByConvertingToUnits:(IJSVGUnitType)unitType
boundingBox:(CGRect)boundingBox;
- (CGFloat)readFloat; - (CGFloat)readFloat;
- (NSPoint)readPoint; - (NSPoint)readPoint;
@@ -42,7 +42,7 @@
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type type:(IJSVGCommandType)type
path:(IJSVGPath*)path path:(CGMutablePathRef)path
{ {
} }
@@ -92,9 +92,95 @@
return nil; 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)dealloc
{ {
(void)([_commandString release]), _commandString = nil;
(void)([_subCommands release]), _subCommands = nil; (void)([_subCommands release]), _subCommands = nil;
if (_parameters) { if (_parameters) {
(void)(free(_parameters)), _parameters = nil; (void)(free(_parameters)), _parameters = nil;
@@ -114,7 +200,7 @@
NSInteger paramCount = [self.class requiredParameterCount]; NSInteger paramCount = [self.class requiredParameterCount];
IJSVGPathDataSequence* sequence = [self.class pathDataSequence]; IJSVGPathDataSequence* sequence = [self.class pathDataSequence];
_parameters = IJSVGParsePathDataStreamSequence(str, strlen(str), _parameters = IJSVGParsePathDataStreamSequence(str, strlen(str),
dataStream, sequence, [self.class requiredParameterCount], &sets); dataStream, sequence, paramCount, &sets);
if (sets <= 1) { if (sets <= 1) {
CGFloat* subParams = [self parametersFromIndexOffset:0]; CGFloat* subParams = [self parametersFromIndexOffset:0];
@@ -151,6 +237,37 @@
return self; 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*)parametersFromIndexOffset:(NSInteger)index
{ {
CGFloat* subParams = 0; CGFloat* subParams = 0;
@@ -202,6 +319,15 @@
_currentIndex = 0; _currentIndex = 0;
} }
- (void)convertToUnits:(IJSVGUnitType)units
boundingBox:(CGRect)boundingBox
{
for(IJSVGCommand* command in _subCommands) {
[command convertToUnits:units
boundingBox:boundingBox];
}
}
- (NSString *)description - (NSString *)description
{ {
NSMutableString* str = [[[NSMutableString alloc] init] autorelease]; NSMutableString* str = [[[NSMutableString alloc] init] autorelease];
@@ -214,4 +340,13 @@
return str; return str;
} }
- (IJSVGCommand*)commandByConvertingToUnits:(IJSVGUnitType)unitType
boundingBox:(CGRect)boundingBox
{
IJSVGCommand* copy = self.copy;
[copy convertToUnits:unitType
boundingBox:boundingBox];
return [copy autorelease];
}
@end @end
@@ -20,9 +20,9 @@
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type type:(IJSVGCommandType)type
path:(IJSVGPath*)path path:(CGMutablePathRef)path
{ {
[path close]; CGPathCloseSubpath(path);
} }
@end @end
@@ -20,16 +20,16 @@
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type type:(IJSVGCommandType)type
path:(IJSVGPath*)path path:(CGMutablePathRef)path
{ {
if (type == kIJSVGCommandTypeAbsolute) { if (type == kIJSVGCommandTypeAbsolute) {
CGPathAddCurveToPoint(path.path, NULL, params[0], params[1], CGPathAddCurveToPoint(path, NULL, params[0], params[1],
params[2], params[3], params[2], params[3],
params[4], params[5]); params[4], params[5]);
return; return;
} }
CGPoint currentPoint = path.currentPoint; CGPoint currentPoint = CGPathGetCurrentPoint(path);
CGPathAddCurveToPoint(path.path, NULL, CGPathAddCurveToPoint(path, NULL,
currentPoint.x + params[0], currentPoint.y + params[1], currentPoint.x + params[0], currentPoint.y + params[1],
currentPoint.x + params[2], currentPoint.y + params[3], currentPoint.x + params[2], currentPoint.y + params[3],
currentPoint.x + params[4], currentPoint.y + params[5]); currentPoint.x + params[4], currentPoint.y + params[5]);
@@ -40,11 +40,11 @@ static IJSVGPathDataSequence* _sequence;
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type type:(IJSVGCommandType)type
path:(IJSVGPath*)path path:(CGMutablePathRef)path
{ {
CGPoint radii = CGPointZero; CGPoint radii = CGPointZero;
CGPoint arcEndPoint = CGPointZero; CGPoint arcEndPoint = CGPointZero;
CGPoint pathCurrentPoint = path.currentPoint; CGPoint pathCurrentPoint = CGPathGetCurrentPoint(path);
CGFloat xAxisRotation = 0.f; CGFloat xAxisRotation = 0.f;
BOOL largeArcFlag = NO; BOOL largeArcFlag = NO;
BOOL sweepFlag = NO; BOOL sweepFlag = NO;
@@ -73,7 +73,7 @@ static IJSVGPathDataSequence* _sequence;
CGFloat y2 = arcEndPoint.y; CGFloat y2 = arcEndPoint.y;
if (rx == 0.f || ry == 0.f) { if (rx == 0.f || ry == 0.f) {
CGPathAddLineToPoint(path.path, NULL, x2, y2); CGPathAddLineToPoint(path, NULL, x2, y2);
return; return;
} }
@@ -132,7 +132,7 @@ static IJSVGPathDataSequence* _sequence;
transform = CGAffineTransformRotate(transform, xAxisRotation); transform = CGAffineTransformRotate(transform, xAxisRotation);
transform = CGAffineTransformScale(transform, rx, ry); 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); startAngle, angleDelta);
} }
@@ -20,15 +20,15 @@
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type type:(IJSVGCommandType)type
path:(IJSVGPath*)path path:(CGMutablePathRef)path
{ {
if (type == kIJSVGCommandTypeAbsolute) { if (type == kIJSVGCommandTypeAbsolute) {
CGPathAddLineToPoint(path.path, NULL, params[0], path.currentPoint.y); CGPathAddLineToPoint(path, NULL, params[0], CGPathGetCurrentPoint(path).y);
return; return;
} }
CGPoint currentPoint = path.currentPoint; CGPoint currentPoint = CGPathGetCurrentPoint(path);
CGPathAddLineToPoint(path.path, NULL, currentPoint.x + params[0], CGPathAddLineToPoint(path, NULL, currentPoint.x + params[0],
path.currentPoint.y); currentPoint.y);
} }
@end @end
@@ -20,15 +20,26 @@
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type type:(IJSVGCommandType)type
path:(IJSVGPath*)path path:(CGMutablePathRef)path
{ {
if (type == kIJSVGCommandTypeAbsolute) { if (type == kIJSVGCommandTypeAbsolute) {
CGPathAddLineToPoint(path.path, NULL, params[0], params[1]); CGPathAddLineToPoint(path, NULL, params[0], params[1]);
return; return;
} }
CGPoint currentPoint = path.currentPoint; CGPoint currentPoint = CGPathGetCurrentPoint(path);
CGPathAddLineToPoint(path.path, NULL, currentPoint.x + params[0], CGPathAddLineToPoint(path, NULL, currentPoint.x + params[0],
currentPoint.y + params[1]); 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 @end
@@ -21,7 +21,7 @@
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type 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, // 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! // 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 // there is no current point. Asking for current point on an empty
// path will result in an exception being thrown // path will result in an exception being thrown
if (type == kIJSVGCommandTypeAbsolute || command == nil) { if (type == kIJSVGCommandTypeAbsolute || command == nil) {
CGPathMoveToPoint(path.path, NULL, CGPathMoveToPoint(path, NULL,
params[0], params[1]); params[0], params[1]);
return; return;
} }
CGPoint currentPoint = path.currentPoint; CGPoint currentPoint = CGPathGetCurrentPoint(path);
CGPathMoveToPoint(path.path, NULL, CGPathMoveToPoint(path, NULL,
currentPoint.x + params[0], currentPoint.x + params[0],
currentPoint.y + params[1]); 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 @end
@@ -21,15 +21,15 @@
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type type:(IJSVGCommandType)type
path:(IJSVGPath*)path path:(CGMutablePathRef)path
{ {
if (type == kIJSVGCommandTypeAbsolute) { if (type == kIJSVGCommandTypeAbsolute) {
CGPathAddQuadCurveToPoint(path.path, NULL, params[0], params[1], CGPathAddQuadCurveToPoint(path, NULL, params[0], params[1],
params[2], params[3]); params[2], params[3]);
return; return;
} }
CGPoint currentPoint = path.currentPoint; CGPoint currentPoint = CGPathGetCurrentPoint(path);
CGPathAddQuadCurveToPoint(path.path, NULL, CGPathAddQuadCurveToPoint(path, NULL,
currentPoint.x + params[0], currentPoint.y + params[1], currentPoint.x + params[0], currentPoint.y + params[1],
currentPoint.x + params[2], currentPoint.y + params[3]); currentPoint.x + params[2], currentPoint.y + params[3]);
} }
@@ -22,9 +22,9 @@
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type type:(IJSVGCommandType)type
path:(IJSVGPath*)path path:(CGMutablePathRef)path
{ {
CGPoint currentPoint = path.currentPoint; CGPoint currentPoint = CGPathGetCurrentPoint(path);
CGPoint firstControl = CGPointMake(currentPoint.x, currentPoint.y); CGPoint firstControl = CGPointMake(currentPoint.x, currentPoint.y);
if (command != nil) { if (command != nil) {
if (command.class == [IJSVGCommandCurve class] || command.class == self.class) { if (command.class == [IJSVGCommandCurve class] || command.class == self.class) {
@@ -52,11 +52,11 @@
} }
} }
if (type == kIJSVGCommandTypeAbsolute) { 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]); params[0], params[1], params[2], params[3]);
return; 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[0], currentPoint.y + params[1],
currentPoint.x + params[2], currentPoint.y + params[3]); currentPoint.x + params[2], currentPoint.y + params[3]);
} }
@@ -22,9 +22,10 @@
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type 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); CGPoint commandPoint = CGPointMake(currentPoint.x, currentPoint.y);
if (command != nil) { if (command != nil) {
if (command.class == IJSVGCommandQuadraticCurve.class) { if (command.class == IJSVGCommandQuadraticCurve.class) {
@@ -40,17 +41,17 @@
} }
} else if (command.class == self.class) { } else if (command.class == self.class) {
// smooth quadratic curve // smooth quadratic curve
commandPoint = CGPointMake(-1 * (path.lastControlPoint.x) + 2 * (currentPoint.x), commandPoint = CGPointMake(-1 * (lastControlPoint.x) + 2 * (currentPoint.x),
-1 * (path.lastControlPoint.y) + 2 * currentPoint.y); -1 * (lastControlPoint.y) + 2 * currentPoint.y);
} }
} }
path.lastControlPoint = commandPoint; // path.lastControlPoint = commandPoint;
if (type == kIJSVGCommandTypeAbsolute) { if (type == kIJSVGCommandTypeAbsolute) {
CGPathAddQuadCurveToPoint(path.path, NULL, commandPoint.x, commandPoint.y, CGPathAddQuadCurveToPoint(path, NULL, commandPoint.x, commandPoint.y,
params[0], params[1]); params[0], params[1]);
return; return;
} }
CGPathAddQuadCurveToPoint(path.path, NULL, commandPoint.x, commandPoint.y, CGPathAddQuadCurveToPoint(path, NULL, commandPoint.x, commandPoint.y,
currentPoint.x + params[0], currentPoint.y + params[1]); currentPoint.x + params[0], currentPoint.y + params[1]);
} }
@@ -20,14 +20,14 @@
command:(IJSVGCommand*)currentCommand command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type type:(IJSVGCommandType)type
path:(IJSVGPath*)path path:(CGMutablePathRef)path
{ {
if (type == kIJSVGCommandTypeAbsolute) { if (type == kIJSVGCommandTypeAbsolute) {
CGPathAddLineToPoint(path.path, NULL, path.currentPoint.x, params[0]); CGPathAddLineToPoint(path, NULL, CGPathGetCurrentPoint(path).x, params[0]);
return; return;
} }
CGPoint currentPoint = path.currentPoint; CGPoint currentPoint = CGPathGetCurrentPoint(path);
CGPathAddLineToPoint(path.path, NULL, currentPoint.x, currentPoint.y + params[0]); CGPathAddLineToPoint(path, NULL, currentPoint.x, currentPoint.y + params[0]);
} }
@end @end
+8 -22
View File
@@ -7,9 +7,11 @@
// //
#import <IJSVG/IJSVGColorList.h> #import <IJSVG/IJSVGColorList.h>
#import <IJSVG/IJSVGRootNode.h>
#import <IJSVG/IJSVGExporter.h> #import <IJSVG/IJSVGExporter.h>
#import <IJSVG/IJSVGGradientLayer.h> #import <IJSVG/IJSVGGradientLayer.h>
#import <IJSVG/IJSVGGroupLayer.h> #import <IJSVG/IJSVGGroupLayer.h>
#import <IJSVG/IJSVGRootLayer.h>
#import <IJSVG/IJSVGImageLayer.h> #import <IJSVG/IJSVGImageLayer.h>
#import <IJSVG/IJSVGLayerTree.h> #import <IJSVG/IJSVGLayerTree.h>
#import <IJSVG/IJSVGParser.h> #import <IJSVG/IJSVGParser.h>
@@ -29,35 +31,25 @@ typedef NS_OPTIONS(NSInteger, IJSVGMatchPropertiesMask) {
@protocol IJSVGDelegate <NSObject, IJSVGParserDelegate> @protocol IJSVGDelegate <NSObject, IJSVGParserDelegate>
@optional @optional
- (BOOL)svg:(IJSVG*)svg
shouldHandleForeignObject:(IJSVGForeignObject*)foreignObject;
- (void)svg:(IJSVG*)svg - (void)svg:(IJSVG*)svg
handleForeignObject:(IJSVGForeignObject*)foreignObject foundSubSVG:(IJSVG*)subSVG
document:(NSXMLDocument*)document; withSVGString:(NSString*)subSVGString;
- (void)svg:(IJSVG*)svg
foundSubSVG:(IJSVG*)subSVG
withSVGString:(NSString*)subSVGString;
@end @end
@interface IJSVG : NSObject <NSPasteboardWriting, IJSVGParserDelegate> { @interface IJSVG : NSObject <NSPasteboardWriting, IJSVGParserDelegate> {
@private @private
IJSVGParser* _group; IJSVGRootNode* _rootNode;
CGFloat _scale; CGFloat _scale;
CGFloat _clipScale; CGFloat _clipScale;
id<IJSVGDelegate> _delegate; id<IJSVGDelegate> _delegate;
IJSVGLayer* _layerTree; IJSVGLayerTree* _layerTree;
CGRect _viewBox; CGRect _viewBox;
CGFloat _backingScaleFactor;
CGFloat _lastProposedBackingScale;
IJSVGRenderQuality _lastProposedRenderQuality;
CGFloat _backingScale; CGFloat _backingScale;
NSMutableDictionary* _replacementColors; NSMutableDictionary* _replacementColors;
struct { struct {
unsigned int shouldHandleForeignObject : 1;
unsigned int handleForeignObject : 1;
unsigned int shouldHandleSubSVG : 1; unsigned int shouldHandleSubSVG : 1;
} _respondsTo; } _respondsTo;
} }
@@ -76,6 +68,8 @@ typedef NS_OPTIONS(NSInteger, IJSVGMatchPropertiesMask) {
@property (nonatomic, readonly) IJSVGUnitSize * intrinsicSize; @property (nonatomic, readonly) IJSVGUnitSize * intrinsicSize;
@property (nonatomic, copy) NSString* title; @property (nonatomic, copy) NSString* title;
@property (nonatomic, copy) NSString* desc; @property (nonatomic, copy) NSString* desc;
@property (nonatomic, retain) IJSVGLayerTree* layerTree;
@property (nonatomic, retain) IJSVGRootLayer* rootLayer;
- (void)prepForDrawingInView:(NSView*)view; - (void)prepForDrawingInView:(NSView*)view;
- (BOOL)isFont; - (BOOL)isFont;
@@ -83,16 +77,11 @@ typedef NS_OPTIONS(NSInteger, IJSVGMatchPropertiesMask) {
- (NSRect)viewBox; - (NSRect)viewBox;
- (NSArray<IJSVGPath*>*)glyphs; - (NSArray<IJSVGPath*>*)glyphs;
- (NSString*)identifier; - (NSString*)identifier;
- (IJSVGLayer*)layer;
- (IJSVGLayer*)layerWithTree:(IJSVGLayerTree*)tree;
- (NSArray<IJSVG*>*)subSVGs:(BOOL)recursive; - (NSArray<IJSVG*>*)subSVGs:(BOOL)recursive;
- (NSString*)SVGStringWithOptions:(IJSVGExporterOptions)options; - (NSString*)SVGStringWithOptions:(IJSVGExporterOptions)options;
- (NSString*)SVGStringWithOptions:(IJSVGExporterOptions)options - (NSString*)SVGStringWithOptions:(IJSVGExporterOptions)options
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions; floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions;
- (CGFloat)computeBackingScale:(CGFloat)scale;
- (void)discardDOM;
+ (id)svgNamed:(NSString*)string; + (id)svgNamed:(NSString*)string;
+ (id)svgNamed:(NSString*)string + (id)svgNamed:(NSString*)string
delegate:(id<IJSVGDelegate>)delegate; delegate:(id<IJSVGDelegate>)delegate;
@@ -169,9 +158,6 @@ typedef NS_OPTIONS(NSInteger, IJSVGMatchPropertiesMask) {
- (NSData*)PDFDataWithRect:(NSRect)rect - (NSData*)PDFDataWithRect:(NSRect)rect
error:(NSError**)error; error:(NSError**)error;
- (void)beginVectorDraw;
- (void)endVectorDraw;
- (NSRect)computeOriginalDrawingFrameWithSize:(NSSize)aSize; - (NSRect)computeOriginalDrawingFrameWithSize:(NSSize)aSize;
- (void)setNeedsDisplay; - (void)setNeedsDisplay;
+171 -242
View File
@@ -23,10 +23,11 @@
(void)([_renderingBackingScaleHelper release]), _renderingBackingScaleHelper = nil; (void)([_renderingBackingScaleHelper release]), _renderingBackingScaleHelper = nil;
(void)([_replacementColors release]), _replacementColors = nil; (void)([_replacementColors release]), _replacementColors = nil;
(void)([_renderingStyle release]), _renderingStyle = nil; (void)([_renderingStyle release]), _renderingStyle = nil;
(void)([_group release]), _group = nil; (void)([_rootNode release]), _rootNode = nil;
(void)([_intrinsicSize release]), _intrinsicSize = nil; (void)([_intrinsicSize release]), _intrinsicSize = nil;
(void)([_title release]), _title = nil; (void)([_title release]), _title = nil;
(void)([_desc release]), _desc = nil; (void)([_desc release]), _desc = nil;
(void)([_rootLayer release]), _rootLayer = nil;
// kill any memory that has been around // kill any memory that has been around
(void)([_layerTree release]), _layerTree = nil; (void)([_layerTree release]), _layerTree = nil;
@@ -107,10 +108,13 @@
__block IJSVGImageLayer* imageLayer = nil; __block IJSVGImageLayer* imageLayer = nil;
// create the layers we require // create the layers we require
IJSVGImage* imageNode = [[[IJSVGImage alloc] init] autorelease];
imageNode.image = image;
BOOL hasTransaction = IJSVGBeginTransaction(); BOOL hasTransaction = IJSVGBeginTransaction();
layer = [[[IJSVGGroupLayer alloc] init] autorelease]; layer = [[[IJSVGGroupLayer alloc] init] autorelease];
imageLayer = imageLayer =
[[[IJSVGImageLayer alloc] initWithImage:image] autorelease]; [[[IJSVGImageLayer alloc] initWithImage:imageNode] autorelease];
[layer addSublayer:imageLayer]; [layer addSublayer:imageLayer];
if (hasTransaction == YES) { if (hasTransaction == YES) {
IJSVGEndTransaction(); IJSVGEndTransaction();
@@ -127,7 +131,6 @@
// this completely bypasses passing of files // this completely bypasses passing of files
if ((self = [super init]) != nil) { if ((self = [super init]) != nil) {
// keep the layer tree // keep the layer tree
_layerTree = [group retain];
_viewBox = viewBox; _viewBox = viewBox;
// any setups // any setups
@@ -205,15 +208,15 @@
[self _checkDelegate]; [self _checkDelegate];
// create the group // create the group
_group = [[IJSVGParser groupForFileURL:aURL IJSVGParser* parser = [IJSVGParser groupForFileURL:aURL
error:&anError error:&anError
delegate:self] retain]; delegate:self];
_rootNode = parser.rootNode.retain;
[self _setupBasicInfoFromGroup]; [self _setupBasicInfoFromGroup];
[self _setupBasicsFromAnyInitializer]; [self _setupBasicsFromAnyInitializer];
// something went wrong... // something went wrong...
if (_group == nil) { if (_rootNode == nil) {
if (error != NULL) { if (error != NULL) {
*error = anError; *error = anError;
} }
@@ -266,15 +269,16 @@
[self _checkDelegate]; [self _checkDelegate];
// setup the parser // setup the parser
_group = [[IJSVGParser alloc] initWithSVGString:string IJSVGParser* parser = [[[IJSVGParser alloc] initWithSVGString:string
error:&anError error:&anError
delegate:self]; delegate:self] autorelease];
_rootNode = parser.rootNode.retain;
[self _setupBasicInfoFromGroup]; [self _setupBasicInfoFromGroup];
[self _setupBasicsFromAnyInitializer]; [self _setupBasicsFromAnyInitializer];
// something went wrong :( // something went wrong :(
if (_group == nil) { if (_rootNode == nil) {
if (error != NULL) { if (error != NULL) {
*error = anError; *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 - (void)_setupBasicInfoFromGroup
{ {
_viewBox = _group.viewBox; _viewBox = [_rootNode.viewBox computeValue:CGSizeZero];
_intrinsicSize = _group.intrinsicSize.retain; _intrinsicSize = _rootNode.intrinsicSize.retain;
} }
- (void)_setupBasicsFromAnyInitializer - (void)_setupBasicsFromAnyInitializer
@@ -317,7 +311,6 @@
self.renderQuality = kIJSVGRenderQualityFullResolution; self.renderQuality = kIJSVGRenderQualityFullResolution;
// setup low level backing scale // setup low level backing scale
_lastProposedBackingScale = 0.f;
self.renderingBackingScaleHelper = ^CGFloat { self.renderingBackingScaleHelper = ^CGFloat {
return NSScreen.mainScreen.backingScaleFactor; return NSScreen.mainScreen.backingScaleFactor;
}; };
@@ -325,37 +318,32 @@
- (void)setTitle:(NSString*)title - (void)setTitle:(NSString*)title
{ {
_group.title = title; _rootNode.title = title;
} }
- (NSString*)title - (NSString*)title
{ {
return _group.title; return _rootNode.title;
} }
- (void)setDesc:(NSString*)description - (void)setDesc:(NSString*)description
{ {
_group.desc = description; _rootNode.desc = description;
} }
- (NSString*)desc - (NSString*)desc
{ {
return _group.desc; return _rootNode.desc;
} }
- (NSString*)identifier - (NSString*)identifier
{ {
return _group.identifier; return _rootNode.identifier;
} }
- (void)_checkDelegate - (void)_checkDelegate
{ {
_respondsTo.shouldHandleForeignObject = _respondsTo.shouldHandleSubSVG = [_delegate respondsToSelector:@selector(svg:foundSubSVG:withSVGString:)];
[_delegate respondsToSelector:@selector(svg:shouldHandleForeignObject:)];
_respondsTo.handleForeignObject = [_delegate
respondsToSelector:@selector(svg:handleForeignObject:document:)];
_respondsTo.shouldHandleSubSVG =
[_delegate respondsToSelector:@selector(svg:foundSubSVG:withSVGString:)];
} }
- (NSRect)viewBox - (NSRect)viewBox
@@ -365,22 +353,22 @@
- (IJSVGGroup*)rootNode - (IJSVGGroup*)rootNode
{ {
return _group; return _rootNode;
} }
- (BOOL)isFont - (BOOL)isFont
{ {
return [_group isFont]; return [_rootNode isFont];
} }
- (NSArray<IJSVGPath*>*)glyphs - (NSArray<IJSVGPath*>*)glyphs
{ {
return [_group glyphs]; return [_rootNode glyphs];
} }
- (NSArray<IJSVG*>*)subSVGs:(BOOL)recursive - (NSArray<IJSVG*>*)subSVGs:(BOOL)recursive
{ {
return [_group subSVGs:recursive]; return [_rootNode subSVGs:recursive];
} }
- (NSString*)SVGStringWithOptions:(IJSVGExporterOptions)options - (NSString*)SVGStringWithOptions:(IJSVGExporterOptions)options
@@ -454,7 +442,7 @@
[self _beginDraw:rect]; [self _beginDraw:rect];
// make sure we setup the scale based on the backing scale factor // 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 // create the context and colorspace
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
@@ -544,10 +532,10 @@
CGContextTranslateCTM(context, 0, -box.size.height); CGContextTranslateCTM(context, 0, -box.size.height);
// make sure we set the masks to path bits n bobs // make sure we set the masks to path bits n bobs
[self _beginVectorDraw]; // [self _beginVectorDraw];
// draw the icon // draw the icon
[self _drawInRect:(NSRect)box context:context error:error]; [self _drawInRect:(NSRect)box context:context error:error];
[self _endVectorDraw]; // [self _endVectorDraw];
CGContextEndPage(context); CGContextEndPage(context);
@@ -558,39 +546,39 @@
return data; return data;
} }
- (void)endVectorDraw //- (void)endVectorDraw
{ //{
[self _endVectorDraw]; // [self _endVectorDraw];
} //}
//
//- (void)beginVectorDraw
//{
// [self _beginVectorDraw];
//}
- (void)beginVectorDraw //- (void)_beginVectorDraw
{ //{
[self _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)_beginVectorDraw // ^void(CALayer* layer, BOOL isMask, BOOL* stop) {
{ // ((IJSVGLayer*)layer).convertMasksToPaths = YES;
// turn on converts masks to PDF's // };
// as PDF context and layer masks dont work // [IJSVGLayer recursivelyWalkLayer:self.layer
void (^block)(CALayer* layer, BOOL isMask, BOOL* stop) = // withBlock:block];
^void(CALayer* layer, BOOL isMask, BOOL* stop) { //}
((IJSVGLayer*)layer).convertMasksToPaths = YES; //
}; //- (void)_endVectorDraw
[IJSVGLayer recursivelyWalkLayer:self.layer //{
withBlock:block]; // // turn of convert masks to paths as not
} // // needed for generic rendering
// void (^block)(CALayer* layer, BOOL isMask, BOOL* stop) =
- (void)_endVectorDraw // ^void(CALayer* layer, BOOL isMask, BOOL* stop) {
{ // ((IJSVGLayer*)layer).convertMasksToPaths = NO;
// turn of convert masks to paths as not // };
// needed for generic rendering // [IJSVGLayer recursivelyWalkLayer:self.layer
void (^block)(CALayer* layer, BOOL isMask, BOOL* stop) = // withBlock:block];
^void(CALayer* layer, BOOL isMask, BOOL* stop) { //}
((IJSVGLayer*)layer).convertMasksToPaths = NO;
};
[IJSVGLayer recursivelyWalkLayer:self.layer
withBlock:block];
}
- (void)prepForDrawingInView:(NSView*)view - (void)prepForDrawingInView:(NSView*)view
{ {
@@ -601,7 +589,7 @@
} }
// construct the layer before drawing // construct the layer before drawing
[self layer]; [self rootLayer];
// set the scale // set the scale
__block NSView* weakView = view; __block NSView* weakView = view;
@@ -647,12 +635,6 @@
error:error]; error:error];
} }
- (CGFloat)computeBackingScale:(CGFloat)actualScale
{
_backingScale = actualScale;
return (CGFloat)(_scale + actualScale);
}
- (NSRect)computeRectDrawingInRect:(NSRect)rect - (NSRect)computeRectDrawingInRect:(NSRect)rect
isValid:(BOOL*)valid isValid:(BOOL*)valid
{ {
@@ -689,152 +671,120 @@
[self _drawInRect:rect context:context error:nil]; [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 - (BOOL)_drawInRect:(NSRect)rect
context:(CGContextRef)ref context:(CGContextRef)ref
error:(NSError**)error error:(NSError**)error
{ {
// prep for draw... BOOL transaction = IJSVGBeginTransaction();
CGContextSaveGState(ref); CGContextSaveGState(ref);
@try { // make sure we setup a transaction
[self _beginDraw:rect]; CGFloat backingScale = [self backingScaleFactor];
[self.rootLayer renderInContext:ref
// we also need to calculate the viewport so we can clip viewPort:rect
// the drawing if needed backingScale:backingScale
BOOL canDraw = NO; quality:_renderQuality];
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); 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; __block CGFloat scale = 1.f;
scale = (self.renderingBackingScaleHelper)(); scale = (self.renderingBackingScaleHelper)();
if (scale < 1.f) { if (scale < 1.f) {
scale = 1.f; scale = 1.f;
} }
_backingScaleFactor = scale; return _backingScale = 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];
} }
- (void)setRenderingStyle:(IJSVGRenderingStyle*)style - (void)setRenderingStyle:(IJSVGRenderingStyle*)style
@@ -867,12 +817,12 @@
- (IJSVGColorList*)colorList - (IJSVGColorList*)colorList
{ {
IJSVGColorList* sheet = [[[IJSVGColorList alloc] init] autorelease]; IJSVGColorList* sheet = [[[IJSVGColorList alloc] init] autorelease];
void (^block)(CALayer* layer, BOOL isMask, BOOL* stop) = void (^block)(CALayer* layer, BOOL* stop) =
^void(CALayer* layer, BOOL isMask, BOOL* stop) { ^void(CALayer* layer, BOOL* stop) {
// dont do anything // dont do anything
if(([layer isKindOfClass:IJSVGShapeLayer.class] && isMask == NO && if(([layer isKindOfClass:IJSVGShapeLayer.class] &&
layer.isHidden == NO) == false) { layer.isHidden == NO) == NO) {
return; return;
} }
@@ -928,7 +878,7 @@
}; };
// gogogo! // gogogo!
[IJSVGLayer recursivelyWalkLayer:self.layer [IJSVGLayer recursivelyWalkLayer:self.rootLayer
withBlock:block]; withBlock:block];
return sheet; 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 #pragma mark matching
- (BOOL)matchesPropertiesWithMask:(IJSVGMatchPropertiesMask)mask - (BOOL)matchesPropertiesWithMask:(IJSVGMatchPropertiesMask)mask
@@ -1017,7 +946,7 @@
IJSVGPath* path = (IJSVGPath*)node; IJSVGPath* path = (IJSVGPath*)node;
if((mask & IJSVGMatchPropertyContainsStrokedElement) != 0 && if((mask & IJSVGMatchPropertyContainsStrokedElement) != 0 &&
[node isKindOfClass:IJSVGPath.class] == YES && [node isKindOfClass:IJSVGPath.class] == YES &&
path.isStroked == YES) { [path matchesTraits:IJSVGNodeTraitStroked] == YES) {
matchedMask |= IJSVGMatchPropertyContainsStrokedElement; matchedMask |= IJSVGMatchPropertyContainsStrokedElement;
} }
@@ -1033,7 +962,7 @@
*stop = YES; *stop = YES;
} }
}; };
[IJSVGNode walkNodeTree:_group [IJSVGNode walkNodeTree:_rootNode
handler:handler]; handler:handler];
return matchedMask == mask; return matchedMask == mask;
} }
@@ -18,6 +18,7 @@
#import "IJSVGRadialGradient.h" #import "IJSVGRadialGradient.h"
#import "IJSVGShapeLayer.h" #import "IJSVGShapeLayer.h"
#import "IJSVGStrokeLayer.h" #import "IJSVGStrokeLayer.h"
#import "IJSVGTransformLayer.h"
@implementation IJSVGExporter @implementation IJSVGExporter
@@ -395,7 +396,7 @@ NSString* IJSVGHash(NSString* key)
_dom.characterEncoding = XML_DOC_CHARSET; _dom.characterEncoding = XML_DOC_CHARSET;
// sort out stuff, so here we go... // sort out stuff, so here we go...
[self _recursiveParseFromLayer:_svg.layer [self _recursiveParseFromLayer:_svg.rootLayer
intoElement:nestedRoot]; intoElement:nestedRoot];
// this needs to be added incase it needs to be cleaned // this needs to be added incase it needs to be cleaned
@@ -1050,10 +1051,12 @@ NSString* IJSVGHash(NSString* key)
if (child != nil) { if (child != nil) {
[element addChild:child]; [element addChild:child];
} }
} else if ([layer isKindOfClass:[IJSVGGroupLayer class]]) { } else if ([layer isKindOfClass:[IJSVGGroupLayer class]] ||
[layer isKindOfClass:IJSVGTransformLayer.class]) {
// assume its probably a group? // assume its probably a group?
NSXMLElement* child = [self elementForGroup:layer NSXMLElement* child = [self elementForGroup:layer
fromParent:element]; fromParent:element];
if (child != nil) { if (child != nil) {
[element addChild:child]; [element addChild:child];
} }
@@ -1137,6 +1140,8 @@ NSString* IJSVGHash(NSString* key)
dict[@"id"] = [self identifierForElement:patternElement]; dict[@"id"] = [self identifierForElement:patternElement];
dict[@"width"] = IJSVGShortFloatStringWithOptions(layer.patternNode.width.value, _floatingPointOptions); dict[@"width"] = IJSVGShortFloatStringWithOptions(layer.patternNode.width.value, _floatingPointOptions);
dict[@"height"] = IJSVGShortFloatStringWithOptions(layer.patternNode.height.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 // sort out x and y position
IJSVGUnitLength* x = layer.patternNode.x; IJSVGUnitLength* x = layer.patternNode.x;
@@ -1207,7 +1212,8 @@ NSString* IJSVGHash(NSString* key)
@"cy" : [rGradient.cy stringValueWithFloatingPointOptions:_floatingPointOptions], @"cy" : [rGradient.cy stringValueWithFloatingPointOptions:_floatingPointOptions],
@"fx" : [rGradient.fx stringValueWithFloatingPointOptions:_floatingPointOptions], @"fx" : [rGradient.fx stringValueWithFloatingPointOptions:_floatingPointOptions],
@"fy" : [rGradient.fy 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 // give it the attributes
IJSVGApplyAttributesToElement(dict, gradientElement); IJSVGApplyAttributesToElement(dict, gradientElement);
@@ -1367,8 +1373,8 @@ NSString* IJSVGHash(NSString* key)
CGPathRef path = layer.path; CGPathRef path = layer.path;
// copy the path as we want to translate // copy the path as we want to translate
CGAffineTransform trans = CGAffineTransformMakeTranslation(layer.originalPathOrigin.x, CGAffineTransform trans = CGAffineTransformMakeTranslation(layer.frame.origin.x,
layer.originalPathOrigin.y); layer.frame.origin.y);
CGPathRef transformPath = CGPathCreateCopyByTransformingPath(path, &trans); CGPathRef transformPath = CGPathCreateCopyByTransformingPath(path, &trans);
NSMutableDictionary* dict = [[[NSMutableDictionary alloc] init] autorelease]; NSMutableDictionary* dict = [[[NSMutableDictionary alloc] init] autorelease];
@@ -14,10 +14,8 @@
@interface IJSVGGradientLayer : IJSVGLayer { @interface IJSVGGradientLayer : IJSVGLayer {
} }
@property (nonatomic, assign) CGRect viewBox;
@property (nonatomic, retain) IJSVGGradient* gradient; @property (nonatomic, retain) IJSVGGradient* gradient;
@property (nonatomic, assign) CGAffineTransform absoluteTransform; @property (nonatomic, assign) CGRect viewBox;
@property (nonatomic, assign) CGRect objectRect;
@end @end
@@ -7,6 +7,7 @@
// //
#import "IJSVGGradientLayer.h" #import "IJSVGGradientLayer.h"
#import <IJSVG/IJSVGRootLayer.h>
@implementation IJSVGGradientLayer @implementation IJSVGGradientLayer
@@ -16,13 +17,9 @@
[super dealloc]; [super dealloc];
} }
- (id)init - (BOOL)requiresBackingScaleHelp
{ {
if ((self = [super init]) != nil) { return YES;
self.requiresBackingScaleHelp = YES;
self.shouldRasterize = YES;
}
return self;
} }
- (void)setGradient:(IJSVGGradient*)newGradient - (void)setGradient:(IJSVGGradient*)newGradient
@@ -74,6 +71,11 @@
[super setBackingScaleFactor:backingScaleFactor]; [super setBackingScaleFactor:backingScaleFactor];
} }
- (CALayer<IJSVGDrawableLayer> *)referencingLayer
{
return [super referencingLayer] ?: self.superlayer;
}
- (void)drawInContext:(CGContextRef)ctx - (void)drawInContext:(CGContextRef)ctx
{ {
[super drawInContext:ctx]; [super drawInContext:ctx];
@@ -84,14 +86,22 @@
} }
// draw the gradient // draw the gradient
CGAffineTransform trans = CGAffineTransformMakeTranslation(-CGRectGetMinX(_objectRect), CALayer<IJSVGDrawableLayer>* layer = (CALayer<IJSVGDrawableLayer>*)self.referencingLayer;
-CGRectGetMinY(_objectRect)); CGRect objectRect = layer.boundingBox;
CGAffineTransform transform = CGAffineTransformConcat(_absoluteTransform, trans); CGRect objectFrame = layer.frame;
CGAffineTransform affine = [IJSVGLayer absoluteTransformForLayer:layer];
affine = CGAffineTransformTranslate(affine,
-CGRectGetMinX(objectFrame),
-CGRectGetMinY(objectFrame));
CGContextSaveGState(ctx); CGContextSaveGState(ctx);
IJSVGRootLayer* rootNode = (IJSVGRootLayer*)[IJSVGLayer rootLayerForLayer:self];
CGRect bounds = [rootNode.viewBox computeValue:CGSizeZero];
[self.gradient drawInContextRef:ctx [self.gradient drawInContextRef:ctx
objectRect:_objectRect objectRect:objectRect
absoluteTransform:transform absoluteTransform:affine
viewPort:self.viewBox]; viewPort:bounds];
CGContextRestoreGState(ctx); CGContextRestoreGState(ctx);
} }
@@ -10,6 +10,12 @@
#import <IJSVG/IJSVGShapeLayer.h> #import <IJSVG/IJSVGShapeLayer.h>
#import <QuartzCore/QuartzCore.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 @end
@@ -7,7 +7,16 @@
// //
#import "IJSVGGroupLayer.h" #import "IJSVGGroupLayer.h"
#import "IJSVGViewBox.h"
#import "IJSVGUnitRect.h"
#import "IJSVGLayer.h"
@implementation IJSVGGroupLayer @implementation IJSVGGroupLayer
- (void)dealloc
{
(void)[_viewBox release], _viewBox = nil;
[super dealloc];
}
@end @end
@@ -7,13 +7,19 @@
// //
#import <IJSVG/IJSVGLayer.h> #import <IJSVG/IJSVGLayer.h>
#import <IJSVG/IJSVGImage.h>
#import <IJSVG/IJSVGTransformLayer.h>
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
#import <QuartzCore/QuartzCore.h> #import <QuartzCore/QuartzCore.h>
@interface IJSVGImageLayer : IJSVGLayer { @interface IJSVGImageLayer : IJSVGLayer {
@private
IJSVGLayer* _imageLayer;
} }
- (id)initWithImage:(NSImage*)image; @property (nonatomic, retain) IJSVGImage* image;
- (id)initWithCGImage:(CGImageRef)imageRef;
- (id)initWithImage:(IJSVGImage*)image;
@end @end
@@ -10,46 +10,44 @@
@implementation IJSVGImageLayer @implementation IJSVGImageLayer
- (id)initWithImage:(NSImage*)image - (void)dealloc
{ {
NSRect rect = (NSRect){ (void)[_image release], _image = nil;
.origin = NSZeroPoint, (void)[_imageLayer release], _imageLayer = nil;
.size = image.size [super dealloc];
};
CGImageRef ref = [image CGImageForProposedRect:&rect
context:nil
hints:nil];
return [self initWithCGImage:ref];
} }
- (id)initWithCGImage:(CGImageRef)imageRef - (id)initWithImage:(IJSVGImage*)image
{ {
if ((self = [super init]) != nil) { if((self = [super init]) != nil) {
// set the contents _image = image.retain;
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))
};
} }
return self; return self;
} }
- (void)setNeedsDisplay - (BOOL)requiresBackingScaleHelp
{ {
// swap the content around on call return YES;
// because set needs display discards previous }
// content - yolo!
id oldContent = self.contents; - (void)layoutSublayers
[super setNeedsDisplay]; {
self.contents = oldContent; [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 @end
@@ -15,8 +15,52 @@
@class IJSVGPatternLayer; @class IJSVGPatternLayer;
@class IJSVGStrokeLayer; @class IJSVGStrokeLayer;
@class IJSVGGroupLayer; @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 @private
IJSVGLayer* _maskingLayer; IJSVGLayer* _maskingLayer;
@@ -27,19 +71,65 @@
@property (nonatomic, assign) IJSVGStrokeLayer* strokeLayer; @property (nonatomic, assign) IJSVGStrokeLayer* strokeLayer;
@property (nonatomic, assign) IJSVGGradientLayer* gradientStrokeLayer; @property (nonatomic, assign) IJSVGGradientLayer* gradientStrokeLayer;
@property (nonatomic, assign) IJSVGPatternLayer* patternStrokeLayer; @property (nonatomic, assign) IJSVGPatternLayer* patternStrokeLayer;
@property (nonatomic, assign) BOOL requiresBackingScaleHelp; @property (nonatomic, readonly) BOOL requiresBackingScaleHelp;
@property (nonatomic, assign) CGFloat backingScaleFactor; @property (nonatomic, assign) CGFloat backingScaleFactor;
@property (nonatomic, assign) IJSVGRenderQuality renderQuality; @property (nonatomic, assign) IJSVGRenderQuality renderQuality;
@property (nonatomic, assign) CGBlendMode blendingMode; @property (nonatomic, assign) CGBlendMode blendingMode;
@property (nonatomic, assign) CGPoint absoluteOrigin; @property (nonatomic, assign) CGPoint absoluteOrigin;
@property (nonatomic, assign) BOOL convertMasksToPaths; @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; + (NSArray*)deepestSublayersOfLayer:(CALayer*)layer;
+ (void)recursivelyWalkLayer:(CALayer*)layer + (void)recursivelyWalkLayer:(CALayer<IJSVGDrawableLayer>*)layer
withBlock:(void (^)(CALayer* layer, BOOL isMask, BOOL* stop))block; withBlock:(void (^)(CALayer<IJSVGDrawableLayer>* layer, BOOL* stop))block;
- (void)applySublayerMaskToContext:(CGContextRef)context - (void)applySublayerMaskToContext:(CGContextRef)context
forSublayer:(IJSVGLayer*)sublayer forSublayer:(IJSVGLayer*)sublayer
withOffset:(CGPoint)offset; 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 @end
+362 -28
View File
@@ -10,15 +10,255 @@
#import "IJSVGGroupLayer.h" #import "IJSVGGroupLayer.h"
#import "IJSVGLayer.h" #import "IJSVGLayer.h"
#import "IJSVGShapeLayer.h" #import "IJSVGShapeLayer.h"
#import "IJSVGTransformLayer.h"
#import "IJSVGRootLayer.h"
@implementation IJSVGLayer @implementation IJSVGLayer
- (void)dealloc - (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; (void)([_maskingLayer release]), _maskingLayer = nil;
[super dealloc]; [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 + (NSArray*)deepestSublayersOfLayer:(CALayer*)layer
{ {
NSMutableArray* arr = [[[NSMutableArray alloc] init] autorelease]; NSMutableArray* arr = [[[NSMutableArray alloc] init] autorelease];
@@ -33,51 +273,90 @@
return arr; return arr;
} }
+ (void)recursivelyWalkLayer:(CALayer*)layer + (void)recursivelyWalkLayer:(CALayer<IJSVGDrawableLayer>*)layer
withBlock:(void (^)(CALayer* layer, BOOL isMask, BOOL* stop))block withBlock:(void (^)(CALayer<IJSVGDrawableLayer>* layer, BOOL* stop))block
{ {
// call for layer and mask if there is one // call for layer and mask if there is one
BOOL stop = NO; BOOL stop = NO;
block(layer, NO, &stop); block(layer, &stop);
if(stop == YES) { if(stop == YES) {
return; return;
} }
// do the mask too!
if (layer.mask != nil) {
block(layer.mask, YES, &stop);
if(stop == YES) {
return;
}
}
// sublayers!! // sublayers!!
for (CALayer* aLayer in layer.sublayers) { for (CALayer<IJSVGDrawableLayer>* aLayer in layer.sublayers) {
[self recursivelyWalkLayer:aLayer [self recursivelyWalkLayer:aLayer
withBlock:block]; 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 - (void)setBackingScaleFactor:(CGFloat)newFactor
{ {
if (_backingScaleFactor == newFactor) { if (_backingScaleFactor == newFactor) {
return; return;
} }
_backingScaleFactor = newFactor; _backingScaleFactor = newFactor;
self.contentsScale = newFactor; self.contentsScale = newFactor;
self.rasterizationScale = newFactor; self.rasterizationScale = newFactor;
// make sure its applied to any mask or clipPath
_maskLayer.backingScaleFactor = newFactor;
_clipLayer.backingScaleFactor = newFactor;
[self setNeedsDisplay]; [self setNeedsDisplay];
} }
- (void)_customRenderInContext:(CGContextRef)ctx - (void)performRenderInContext:(CGContextRef)ctx
{ {
if (_convertMasksToPaths == YES && _maskingLayer != nil) { if(_maskLayer != nil) {
CGContextSaveGState(ctx); [self.class clipContextWithMask:_maskLayer
[self applySublayerMaskToContext:ctx toLayer:self
forSublayer:(IJSVGLayer*)self inContext:ctx
withOffset:CGPointZero]; drawingBlock:^{
[super renderInContext:ctx]; [super renderInContext:ctx];
CGContextRestoreGState(ctx); }];
return; return;
} }
[super renderInContext:ctx]; [super renderInContext:ctx];
@@ -141,6 +420,21 @@
CGContextConcatCTM(context, sublayerTransform); 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 - (IJSVGShapeLayer*)maskingLayer
{ {
return (IJSVGShapeLayer*)_maskingLayer ?: nil; return (IJSVGShapeLayer*)_maskingLayer ?: nil;
@@ -148,14 +442,8 @@
- (void)renderInContext:(CGContextRef)ctx - (void)renderInContext:(CGContextRef)ctx
{ {
if (_blendingMode != kCGBlendModeNormal) { [IJSVGLayer renderLayer:self
CGContextSaveGState(ctx); inContext:ctx];
CGContextSetBlendMode(ctx, _blendingMode);
[self _customRenderInContext:ctx];
CGContextRestoreGState(ctx);
return;
}
[self _customRenderInContext:ctx];
} }
- (id<CAAction>)actionForKey:(NSString*)event - (id<CAAction>)actionForKey:(NSString*)event
@@ -163,4 +451,50 @@
return nil; 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 @end
@@ -12,7 +12,7 @@
@interface IJSVGPatternLayer : IJSVGLayer @interface IJSVGPatternLayer : IJSVGLayer
@property (nonatomic, retain) IJSVGLayer* pattern; @property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* pattern;
@property (nonatomic, retain) IJSVGPattern* patternNode; @property (nonatomic, retain) IJSVGPattern* patternNode;
@end @end
@@ -6,7 +6,17 @@
// Copyright © 2017 Curtis Hard. All rights reserved. // 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 @implementation IJSVGPatternLayer
@@ -17,22 +27,40 @@
[super dealloc]; [super dealloc];
} }
- (id)init - (BOOL)requiresBackingScaleHelp
{ {
if ((self = [super init]) != nil) { return YES;
self.requiresBackingScaleHelp = YES;
self.shouldRasterize = YES;
}
return self;
} }
void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx) void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
{ {
// reassign the layer // reassign the layer
IJSVGPatternLayer* layer = (IJSVGPatternLayer*)info; 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 - (void)drawInContext:(CGContextRef)ctx
{ {
// holder for callback // holder for callback
@@ -43,12 +71,53 @@ void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
CGContextSetFillColorSpace(ctx, patternSpace); CGContextSetFillColorSpace(ctx, patternSpace);
CGColorSpaceRelease(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 // create the pattern
CGRect rect = self.bounds; CGRect selfBounds = self.boundingBoxBounds;
CGPatternRef ref = CGPatternCreate((void*)self, self.bounds, CGPatternRef ref = CGPatternCreate((void*)self, selfBounds,
CGAffineTransformIdentity, transform, width, height,
roundf(rect.size.width * _patternNode.width.value),
roundf(rect.size.height * _patternNode.height.value),
kCGPatternTilingConstantSpacing, kCGPatternTilingConstantSpacing,
true, &callbacks); true, &callbacks);
@@ -58,7 +127,12 @@ void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
CGPatternRelease(ref); CGPatternRelease(ref);
// fill it // fill it
CGContextFillRect(ctx, rect); CGContextFillRect(ctx, selfBounds);
}
- (NSArray<CALayer<IJSVGDrawableLayer>*>*)debugLayers
{
return @[self.pattern];
} }
@end @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 <IJSVG/IJSVGUtils.h>
#import <QuartzCore/QuartzCore.h> #import <QuartzCore/QuartzCore.h>
@interface IJSVGShapeLayer : CAShapeLayer { @interface IJSVGShapeLayer : CAShapeLayer <IJSVGDrawableLayer, IJSVGPathableLayer> {
@private @private
IJSVGLayer* _maskingLayer; IJSVGLayer* _maskingLayer;
@@ -21,14 +21,25 @@
@property (nonatomic, assign) IJSVGStrokeLayer* strokeLayer; @property (nonatomic, assign) IJSVGStrokeLayer* strokeLayer;
@property (nonatomic, assign) IJSVGGradientLayer* gradientStrokeLayer; @property (nonatomic, assign) IJSVGGradientLayer* gradientStrokeLayer;
@property (nonatomic, assign) IJSVGPatternLayer* patternStrokeLayer; @property (nonatomic, assign) IJSVGPatternLayer* patternStrokeLayer;
@property (nonatomic, assign) BOOL requiresBackingScaleHelp;
@property (nonatomic, assign) CGFloat backingScaleFactor; @property (nonatomic, assign) CGFloat backingScaleFactor;
@property (nonatomic, readonly) BOOL requiresBackingScaleHelp;
@property (nonatomic, assign) IJSVGRenderQuality renderQuality; @property (nonatomic, assign) IJSVGRenderQuality renderQuality;
@property (nonatomic, assign) CGBlendMode blendingMode; @property (nonatomic, assign) CGBlendMode blendingMode;
@property (nonatomic, assign) CGPoint absoluteOrigin; @property (nonatomic, assign) CGPoint absoluteOrigin;
@property (nonatomic, assign) CGPoint originalPathOrigin; @property (nonatomic, assign) CGPoint originalPathOrigin;
@property (nonatomic, assign) BOOL convertMasksToPaths; @property (nonatomic, assign) BOOL convertMasksToPaths;
@property (nonatomic, assign) IJSVGPrimitivePathType primitiveType; @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 - (void)applySublayerMaskToContext:(CGContextRef)context
forSublayer:(IJSVGLayer*)sublayer forSublayer:(IJSVGLayer*)sublayer
@@ -13,30 +13,72 @@
- (void)dealloc - (void)dealloc
{ {
(void)([_clipLayer release]), _clipLayer = nil;
(void)([_maskLayer release]), _maskLayer = nil;
(void)([_maskingLayer release]), _maskingLayer = nil; (void)([_maskingLayer release]), _maskingLayer = nil;
(void)([_clipRule release]), _clipRule = nil;
[super dealloc]; [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 - (void)setBackingScaleFactor:(CGFloat)newFactor
{ {
if (self.backingScaleFactor == newFactor) { if (_backingScaleFactor == newFactor) {
return; return;
} }
_backingScaleFactor = newFactor; _backingScaleFactor = newFactor;
self.contentsScale = newFactor; self.contentsScale = newFactor;
self.rasterizationScale = newFactor; self.rasterizationScale = newFactor;
// make sure its applied to any mask or clipPath
_maskLayer.backingScaleFactor = newFactor;
_clipLayer.backingScaleFactor = newFactor;
[self setNeedsDisplay]; [self setNeedsDisplay];
} }
- (void)_customRenderInContext:(CGContextRef)ctx - (void)performRenderInContext:(CGContextRef)ctx
{ {
if (self.convertMasksToPaths == YES && _maskingLayer != nil) { if(_maskLayer != nil) {
CGContextSaveGState(ctx); [IJSVGLayer clipContextWithMask:_maskLayer
[self applySublayerMaskToContext:ctx toLayer:self
forSublayer:(IJSVGLayer*)self inContext:ctx
withOffset:CGPointZero]; drawingBlock:^{
[super renderInContext:ctx]; [super renderInContext:ctx];
CGContextRestoreGState(ctx); }];
return; return;
} }
[super renderInContext:ctx]; [super renderInContext:ctx];
@@ -107,26 +149,8 @@
- (void)renderInContext:(CGContextRef)ctx - (void)renderInContext:(CGContextRef)ctx
{ {
if (self.blendingMode != kCGBlendModeNormal) { [IJSVGLayer renderLayer:(IJSVGLayer*)self
CGContextSaveGState(ctx); inContext: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;
} }
- (id<CAAction>)actionForKey:(NSString*)event - (id<CAAction>)actionForKey:(NSString*)event
@@ -134,4 +158,9 @@
return nil; return nil;
} }
-(NSArray<CALayer<IJSVGDrawableLayer>*>*)debugLayers
{
return self.sublayers;
}
@end @end
@@ -10,4 +10,11 @@
@implementation IJSVGStrokeLayer @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 @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. // Copyright (c) 2014 Curtis Hard. All rights reserved.
// //
#import <Foundation/Foundation.h>
#import <IJSVG/IJSVGColorList.h> #import <IJSVG/IJSVGColorList.h>
#import <IJSVG/IJSVGDef.h> #import <IJSVG/IJSVGDef.h>
#import <IJSVG/IJSVGTransform.h> #import <IJSVG/IJSVGTransform.h>
#import <IJSVG/IJSVGGroup.h> #import <IJSVG/IJSVGGroup.h>
#import <Foundation/Foundation.h>
@interface IJSVGGradient : IJSVGGroup @interface IJSVGGradient : IJSVGGroup
@@ -47,13 +47,13 @@
+ (CGFloat *)computeColorStops:(IJSVGGradient*)gradient + (CGFloat *)computeColorStops:(IJSVGGradient*)gradient
colors:(NSArray**)someColors colors:(NSArray**)someColors
{ {
NSArray<IJSVGNode*>* stops = gradient.childNodes; NSArray<IJSVGNode*>* stops = gradient.children;
NSMutableArray* colors = [[[NSMutableArray alloc] initWithCapacity:stops.count] autorelease]; NSMutableArray* colors = [[[NSMutableArray alloc] initWithCapacity:stops.count] autorelease];
CGFloat* stopsParams = (CGFloat*)malloc(stops.count * sizeof(CGFloat)); CGFloat* stopsParams = (CGFloat*)malloc(stops.count * sizeof(CGFloat));
NSInteger i = 0; NSInteger i = 0;
for(IJSVGNode* stopNode in stops) { for(IJSVGNode* stopNode in stops) {
NSColor* color = stopNode.fillColor; NSColor* color = ((IJSVGColorNode*)(stopNode.fill)).color;
CGFloat opacity = stopNode.fillOpacity.value; CGFloat opacity = stopNode.fillOpacity.value;
CGFloat offset = stopNode.offset.value; CGFloat offset = stopNode.offset.value;
stopsParams[i++] = offset; stopsParams[i++] = offset;
@@ -100,7 +100,7 @@
// actually create the gradient // actually create the gradient
NSInteger num = self.gradient.numberOfColorStops; NSInteger num = self.gradient.numberOfColorStops;
CGFloat* locations = malloc(sizeof(CGFloat) * num); CGFloat* locations = (CGFloat*)malloc(sizeof(CGFloat) * num);
CFMutableArrayRef colors = CFArrayCreateMutable(kCFAllocatorDefault, (CFIndex)num, CFMutableArrayRef colors = CFArrayCreateMutable(kCFAllocatorDefault, (CFIndex)num,
&kCFTypeArrayCallBacks); &kCFTypeArrayCallBacks);
for (NSInteger i = 0; i < num; i++) { for (NSInteger i = 0; i < num; i++) {
@@ -113,7 +113,7 @@
} }
CFArrayAppendValue(colors, color.CGColor); CFArrayAppendValue(colors, color.CGColor);
} }
CGGradientRef result = CGGradientCreateWithColors(self.gradient.colorSpace.CGColorSpace, CGGradientRef result = CGGradientCreateWithColors(_gradient.colorSpace.CGColorSpace,
colors, locations); colors, locations);
CFRelease(colors); CFRelease(colors);
free(locations); free(locations);
@@ -13,11 +13,11 @@
@interface IJSVGGroup : IJSVGNode { @interface IJSVGGroup : IJSVGNode {
@private @private
NSMutableArray<IJSVGNode*>* _childNodes; NSMutableArray<IJSVGNode*>* _children;
} }
@property (nonatomic, readonly) NSArray<IJSVGNode*>* children;
- (void)addChild:(IJSVGNode*)child; - (void)addChild:(IJSVGNode*)child;
- (NSArray<IJSVGNode*>*)childNodes;
- (void)purgeChildren;
@end @end
+30 -16
View File
@@ -12,24 +12,24 @@
- (void)dealloc - (void)dealloc
{ {
(void)([_childNodes release]), _childNodes = nil; (void)([_children release]), _children = nil;
[super dealloc]; [super dealloc];
} }
- (id)init - (id)init
{ {
if ((self = [super init]) != nil) { if ((self = [super init]) != nil) {
_childNodes = [[NSMutableArray alloc] init]; _children = [[NSMutableArray alloc] init];
} }
return self; return self;
} }
- (void)prepareFromCopy - (void)prepareFromCopy
{ {
if(_childNodes != nil) { if(_children != nil) {
(void)[_childNodes release], _childNodes = nil; (void)[_children release], _children = nil;
} }
_childNodes = [[NSMutableArray alloc] init]; _children = [[NSMutableArray alloc] init];
} }
- (id)copyWithZone:(NSZone*)zone - (id)copyWithZone:(NSZone*)zone
@@ -37,7 +37,7 @@
IJSVGGroup* node = [super copyWithZone:zone]; IJSVGGroup* node = [super copyWithZone:zone];
[node prepareFromCopy]; [node prepareFromCopy];
for (IJSVGNode* childNode in _childNodes) { for (IJSVGNode* childNode in _children) {
childNode = [[childNode copy] autorelease]; childNode = [[childNode copy] autorelease];
childNode.parentNode = node; childNode.parentNode = node;
[node addChild:childNode]; [node addChild:childNode];
@@ -45,27 +45,41 @@
return node; return node;
} }
- (void)purgeChildren
{
[_childNodes removeAllObjects];
}
- (void)addChild:(IJSVGNode*)child - (void)addChild:(IJSVGNode*)child
{ {
if (child != nil) { if(child == nil || (child.parentNode == self && [_children containsObject:child])) {
[_childNodes addObject: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 - (NSString*)description
{ {
return [NSString stringWithFormat:@"%@ - %@", return [NSString stringWithFormat:@"%@ - %@",
[super description], self.childNodes]; [super description], self.children];
} }
@end @end
@@ -12,15 +12,15 @@
@class IJSVGPath; @class IJSVGPath;
@interface IJSVGImage : IJSVGNode { @interface IJSVGImage : IJSVGNode {
NSImage* image;
CGImageRef CGImage; 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; - (CGImageRef)CGImage;
- (void)drawInContextRef:(CGContextRef)context
path:(IJSVGPath*)path;
- (void)loadFromString:(NSString*)encodedString; - (void)loadFromString:(NSString*)encodedString;
- (void)loadFromURL:(NSURL*)aURL; - (void)loadFromURL:(NSURL*)aURL;
+26 -45
View File
@@ -15,8 +15,7 @@
- (void)dealloc - (void)dealloc
{ {
(void)(CGImageRelease(CGImage)), CGImage = nil; (void)(CGImageRelease(CGImage)), CGImage = nil;
(void)([imagePath release]), imagePath = nil; (void)([_image release]), _image = nil;
(void)([image release]), image = nil;
[super dealloc]; [super dealloc];
} }
@@ -48,36 +47,24 @@
[self setImage:anImage]; [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 - (void)setImage:(NSImage*)anImage
{ {
if (image != nil) { if (_image != nil) {
(void)([image release]), image = nil; (void)([_image release]), _image = nil;
} }
image = [anImage retain]; _image = [anImage retain];
_intrinsicSize = (CGSize)_image.size;
if (CGImage != nil) { if (CGImage != nil) {
CGImageRelease(CGImage); CGImageRelease(CGImage);
CGImage = nil; CGImage = nil;
} }
NSRect rect = NSMakeRect(0.f, 0.f, self.width.value, self.height.value); NSRect rect = NSMakeRect(0.f, 0.f, _intrinsicSize.width, _intrinsicSize.height);
CGImage = [image CGImageForProposedRect:&rect CGImage = [_image CGImageForProposedRect:&rect
context:nil context:nil
hints:nil]; hints:nil];
// be sure to retain (some reason this is required in Xcode 8 beta 5?)
CGImageRetain(CGImage); CGImageRetain(CGImage);
} }
@@ -86,32 +73,26 @@
return CGImage; return CGImage;
} }
- (void)drawInContextRef:(CGContextRef)context - (CGRect)intrinsicBounds
path:(IJSVGPath*)path
{ {
// run the transforms CGRect rect = CGRectZero;
// draw the image rect.size.width = _intrinsicSize.width;
if (self.width.value == 0.f || self.height.value == 0.f) { rect.size.height = _intrinsicSize.height;
return; return rect;
} }
// make sure path is set - (CGAffineTransform)intrinsicTransform
if (path == nil) { {
path = [self path]; CGFloat widthRatio = self.width.value / _intrinsicSize.width;
} CGFloat heightRatio = self.height.value / _intrinsicSize.height;
return CGAffineTransformMakeScale(widthRatio, heightRatio);
}
CGRect rect = path.pathBoundingBox; - (CGRect)bounds
CGRect bounds = CGRectMake(0.f, 0.f, rect.size.width, rect.size.height); {
return CGRectMake(0.f, 0.f,
// save the state of the context self.width.value,
CGContextSaveGState(context); self.height.value);
{
// 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);
} }
@end @end
+30 -13
View File
@@ -8,20 +8,28 @@
#import <IJSVG/IJSVGStyle.h> #import <IJSVG/IJSVGStyle.h>
#import <IJSVG/IJSVGUnitLength.h> #import <IJSVG/IJSVGUnitLength.h>
#import <IJSVG/IJSVGViewBox.h>
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@class IJSVGNode; @class IJSVGNode;
@class IJSVG; @class IJSVG;
@class IJSVGGroup; @class IJSVGGroup;
@class IJSVGDef;
@class IJSVGGradient; @class IJSVGGradient;
@class IJSVGGroup; @class IJSVGGroup;
@class IJSVGPattern; @class IJSVGPattern;
@class IJSVGTransform; @class IJSVGTransform;
@class IJSVGRootNode;
@class IJSVGUnitRect;
typedef void (^IJSVGNodeWalkHandler)(IJSVGNode* node, BOOL* allowChildNodes, BOOL* stop); 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) { typedef NS_ENUM(NSInteger, IJSVGNodeType) {
IJSVGNodeTypeGroup, IJSVGNodeTypeGroup,
IJSVGNodeTypePath, IJSVGNodeTypePath,
@@ -50,6 +58,7 @@ typedef NS_ENUM(NSInteger, IJSVGNodeType) {
IJSVGNodeTypeDesc, IJSVGNodeTypeDesc,
IJSVGNodeTypeStop, IJSVGNodeTypeStop,
IJSVGNodeTypeNotFound, IJSVGNodeTypeNotFound,
IJSVGNodeTypeUnknown,
}; };
typedef NS_ENUM(NSInteger, IJSVGWindingRule) { typedef NS_ENUM(NSInteger, IJSVGWindingRule) {
@@ -108,6 +117,13 @@ static CGFloat IJSVGInheritedFloatValue = -99.9999991;
@interface IJSVGNode : NSObject <NSCopying> @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* title;
@property (nonatomic, copy) NSString* desc; @property (nonatomic, copy) NSString* desc;
@property (nonatomic, assign) IJSVGNodeType type; @property (nonatomic, assign) IJSVGNodeType type;
@@ -116,7 +132,6 @@ static CGFloat IJSVGInheritedFloatValue = -99.9999991;
@property (nonatomic, retain) NSArray* classNameList; @property (nonatomic, retain) NSArray* classNameList;
@property (nonatomic, copy) NSString* unicode; @property (nonatomic, copy) NSString* unicode;
@property (nonatomic, assign) BOOL shouldRender; @property (nonatomic, assign) BOOL shouldRender;
@property (nonatomic, assign) BOOL usesDefaultFillColor;
@property (nonatomic, retain) IJSVGUnitLength* x; @property (nonatomic, retain) IJSVGUnitLength* x;
@property (nonatomic, retain) IJSVGUnitLength* y; @property (nonatomic, retain) IJSVGUnitLength* y;
@property (nonatomic, retain) IJSVGUnitLength* width; @property (nonatomic, retain) IJSVGUnitLength* width;
@@ -126,24 +141,19 @@ static CGFloat IJSVGInheritedFloatValue = -99.9999991;
@property (nonatomic, retain) IJSVGUnitLength* strokeOpacity; @property (nonatomic, retain) IJSVGUnitLength* strokeOpacity;
@property (nonatomic, retain) IJSVGUnitLength* strokeWidth; @property (nonatomic, retain) IJSVGUnitLength* strokeWidth;
@property (nonatomic, retain) IJSVGUnitLength* offset; @property (nonatomic, retain) IJSVGUnitLength* offset;
@property (nonatomic, retain) NSColor* fillColor; @property (nonatomic, retain) IJSVGNode* fill;
@property (nonatomic, retain) NSColor* strokeColor; @property (nonatomic, retain) IJSVGNode* stroke;
@property (nonatomic, copy) NSString* identifier; @property (nonatomic, copy) NSString* identifier;
@property (nonatomic, assign) IJSVGNode* parentNode; @property (nonatomic, assign) IJSVGNode* parentNode;
@property (nonatomic, assign) IJSVGNode* intermediateParentNode;
@property (nonatomic, retain) IJSVGGroup* clipPath; @property (nonatomic, retain) IJSVGGroup* clipPath;
@property (nonatomic, retain) IJSVGGroup* mask; @property (nonatomic, retain) IJSVGGroup* mask;
@property (nonatomic, assign) IJSVGWindingRule windingRule; @property (nonatomic, assign) IJSVGWindingRule windingRule;
@property (nonatomic, assign) IJSVGLineCapStyle lineCapStyle; @property (nonatomic, assign) IJSVGLineCapStyle lineCapStyle;
@property (nonatomic, assign) IJSVGLineJoinStyle lineJoinStyle; @property (nonatomic, assign) IJSVGLineJoinStyle lineJoinStyle;
@property (nonatomic, retain) NSArray<IJSVGTransform*>* transforms; @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) CGFloat* strokeDashArray;
@property (nonatomic, assign) NSInteger strokeDashArrayCount; @property (nonatomic, assign) NSInteger strokeDashArrayCount;
@property (nonatomic, readonly) NSArray<NSNumber*>* lineDashPattern;
@property (nonatomic, retain) IJSVGUnitLength* strokeDashOffset; @property (nonatomic, retain) IJSVGUnitLength* strokeDashOffset;
@property (nonatomic, retain) IJSVG* svg; @property (nonatomic, retain) IJSVG* svg;
@property (nonatomic, assign) IJSVGUnitType contentUnits; @property (nonatomic, assign) IJSVGUnitType contentUnits;
@@ -158,8 +168,15 @@ static CGFloat IJSVGInheritedFloatValue = -99.9999991;
kind:(NSXMLNodeKind)kind; kind:(NSXMLNodeKind)kind;
- (void)applyPropertiesFromNode:(IJSVGNode*)node; - (void)applyPropertiesFromNode:(IJSVGNode*)node;
- (id)initWithDef:(BOOL)flag;
- (void)addDef:(IJSVGNode*)aDef; - (IJSVGUnitType)contentUnitsWithReferencingNodeBounds:(CGRect*)bounds;
- (IJSVGDef*)defForID:(NSString*)anID; - (IJSVGUnitType)contentUnitsWithReferencingNode:(IJSVGNode**)referencingNode;
- (instancetype)detach;
- (void)addTraits:(IJSVGNodeTraits)traits;
- (void)removeTraits:(IJSVGNodeTraits)traits;
- (BOOL)matchesTraits:(IJSVGNodeTraits)traits;
- (void)computeTraits;
@end @end
+122 -107
View File
@@ -6,13 +6,16 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved. // Copyright (c) 2014 Curtis Hard. All rights reserved.
// //
#import "IJSVGDef.h" #import <IJSVG/IJSVGDef.h>
#import "IJSVGNode.h" #import <IJSVG/IJSVGNode.h>
#import "IJSVGUtils.h" #import <IJSVG/IJSVGGroup.h>
#import "IJSVGGroup.h" #import <IJSVG/IJSVGUtils.h>
@implementation IJSVGNode @implementation IJSVGNode
@synthesize fill = _fill;
@synthesize stroke = _stroke;
- (void)dealloc - (void)dealloc
{ {
(void)free(_strokeDashArray), _strokeDashArray = NULL; (void)free(_strokeDashArray), _strokeDashArray = NULL;
@@ -27,23 +30,19 @@
(void)([_strokeWidth release]), _strokeWidth = nil; (void)([_strokeWidth release]), _strokeWidth = nil;
(void)([_strokeDashOffset release]), _strokeDashOffset = nil; (void)([_strokeDashOffset release]), _strokeDashOffset = nil;
(void)([_unicode release]), _unicode = nil; (void)([_unicode release]), _unicode = nil;
(void)([_fillGradient release]), _fillGradient = nil; (void)([_fill release]), _fill = nil;
(void)([_strokeGradient release]), _strokeGradient = nil; (void)([_stroke release]), _stroke = nil;
(void)([_strokePattern release]), _strokePattern = nil;
(void)([_transforms release]), _transforms = nil; (void)([_transforms release]), _transforms = nil;
(void)([_fillColor release]), _fillColor = nil;
(void)([_strokeColor release]), _strokeColor = nil;
(void)([_identifier release]), _identifier = nil; (void)([_identifier release]), _identifier = nil;
(void)([_def release]), _def = nil;
(void)([_name release]), _name = nil; (void)([_name release]), _name = nil;
(void)([_title release]), _title = nil; (void)([_title release]), _title = nil;
(void)([_desc release]), _desc = nil; (void)([_desc release]), _desc = nil;
(void)([_className release]), _className = nil; (void)([_className release]), _className = nil;
(void)([_classNameList release]), _classNameList = nil; (void)([_classNameList release]), _classNameList = nil;
(void)([_fillPattern release]), _fillPattern = nil;
(void)([_clipPath release]), _clipPath = nil; (void)([_clipPath release]), _clipPath = nil;
(void)([_svg release]), _svg = nil; (void)([_svg release]), _svg = nil;
(void)([_mask release]), _mask = nil; (void)([_mask release]), _mask = nil;
(void)([_viewBox release]), _viewBox = nil;
[super dealloc]; [super dealloc];
} }
@@ -137,15 +136,7 @@
if(strcmp(name, "desc") == 0) { if(strcmp(name, "desc") == 0) {
return IJSVGNodeTypeDesc; return IJSVGNodeTypeDesc;
} }
return IJSVGNodeTypeNotFound; return IJSVGNodeTypeUnknown;
}
- (id)init
{
if ((self = [self initWithDef:YES]) != nil) {
self.opacity = [IJSVGUnitLength unitWithFloat:1];
}
return self;
} }
+ (void)walkNodeTree:(IJSVGNode*)node + (void)walkNodeTree:(IJSVGNode*)node
@@ -181,7 +172,7 @@
// iterate over the childnodes // iterate over the childnodes
IJSVGGroup* group = (IJSVGGroup*)node; IJSVGGroup* group = (IJSVGGroup*)node;
for(IJSVGNode* childNode in group.childNodes) { for(IJSVGNode* childNode in group.children) {
[self _walkNodeTree:childNode [self _walkNodeTree:childNode
handler:handler handler:handler
allowChildNodes:allowChildNodes 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 - (void)applyPropertiesFromNode:(IJSVGNode*)node
{ {
self.title = node.title; self.title = node.title;
@@ -203,18 +223,17 @@
self.className = node.className; self.className = node.className;
self.classNameList = node.classNameList; self.classNameList = node.classNameList;
self.viewBox = node.viewBox;
self.viewBoxAlignment = node.viewBoxAlignment;
self.viewBoxMeetOrSlice = node.viewBoxMeetOrSlice;
self.x = node.x; self.x = node.x;
self.y = node.y; self.y = node.y;
self.width = node.width; self.width = node.width;
self.height = node.height; self.height = node.height;
self.fillGradient = node.fillGradient; self.fill = node.fill;
self.fillPattern = node.fillPattern; self.stroke = node.stroke;
self.strokeGradient = node.strokeGradient;
self.strokePattern = node.strokePattern;
self.fillColor = node.fillColor;
self.strokeColor = node.strokeColor;
self.clipPath = node.clipPath; self.clipPath = node.clipPath;
self.units = node.units; self.units = node.units;
@@ -226,10 +245,8 @@
self.strokeOpacity = node.strokeOpacity; self.strokeOpacity = node.strokeOpacity;
self.identifier = node.identifier; self.identifier = node.identifier;
self.usesDefaultFillColor = node.usesDefaultFillColor;
self.transforms = node.transforms; self.transforms = node.transforms;
self.def = node.def;
self.windingRule = node.windingRule; self.windingRule = node.windingRule;
self.lineCapStyle = node.lineCapStyle; self.lineCapStyle = node.lineCapStyle;
self.lineJoinStyle = node.lineJoinStyle; self.lineJoinStyle = node.lineJoinStyle;
@@ -254,52 +271,18 @@
return node; return node;
} }
- (id)initWithDef:(BOOL)flag - (void)setFill:(IJSVGNode*)fill
{ {
if ((self = [super init]) != nil) { NSAssert([fill matchesTraits:IJSVGNodeTraitPaintable] || fill == nil, @"Fill must a paintable node.");
self.opacity = [IJSVGUnitLength unitWithFloat:0.f]; (void)[_fill release], _fill = nil;
self.fillOpacity = [IJSVGUnitLength unitWithFloat:1.f]; _fill = [fill retain];
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;
} }
- (IJSVGDef*)defForID:(NSString*)anID - (void)setStroke:(IJSVGNode*)stroke
{ {
IJSVGDef* aDef = nil; NSAssert([stroke matchesTraits:IJSVGNodeTraitPaintable]|| stroke == nil, @"Stroke must be a paintable node.");
if ((aDef = [_def defForID:anID]) != nil) { (void)[_stroke release], _stroke = nil;
return aDef; _stroke = [stroke retain];
}
if (_parentNode != nil) {
return [_parentNode defForID:anID];
}
return nil;
}
- (void)addDef:(IJSVGNode*)aDef
{
[_def addDef:aDef];
} }
// winding rule can inherit.. // winding rule can inherit..
@@ -361,15 +344,23 @@
return _strokeWidth; 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 // these are all recursive, so go up the chain
// if they dont exist on this specific node // if they dont exist on this specific node
- (NSColor*)strokeColor - (IJSVGNode*)stroke
{ {
if (_strokeColor != nil) if (_stroke == nil && _parentNode != nil) {
return _strokeColor; return _parentNode.stroke;
if (_strokeColor == nil && _parentNode != nil) }
return _parentNode.strokeColor; return _stroke;
return nil;
} }
- (IJSVGUnitLength*)strokeOpacity - (IJSVGUnitLength*)strokeOpacity
@@ -382,52 +373,76 @@
// even though the spec explicity states fill color // even though the spec explicity states fill color
// must be on the path, it can also be on the // must be on the path, it can also be on the
- (NSColor*)fillColor - (IJSVGNode*)fill
{ {
if (_fillColor == nil && _parentNode != nil) { if (_fill == nil && _parentNode != nil) {
return _parentNode.fillColor; return _parentNode.fill;
} }
return _fillColor; return _fill;
} }
// these are all recursive, so go up the chain - (IJSVGUnitType)units
// if they dont exist on this specific node
- (IJSVGGradient*)fillGradient
{ {
if (_fillGradient == nil && _parentNode != nil) { if(_units == IJSVGUnitInherit && _parentNode != nil) {
return _parentNode.fillGradient; return _parentNode.units;
} }
return _fillGradient; return _units;
} }
// these are all recursive, so go up the chain - (IJSVGUnitType)contentUnits
// if they dont exist on this specific node
- (IJSVGPattern*)fillPattern
{ {
if (_fillPattern == nil && _parentNode != nil) { if(_contentUnits == IJSVGUnitInherit && _parentNode != nil) {
return _parentNode.fillPattern; return _parentNode.contentUnits;
} }
return _fillPattern; return _contentUnits;
} }
// these are all recursive, so go up the chain - (IJSVGUnitType)contentUnitsWithReferencingNodeBounds:(CGRect*)bounds
// if they dont exist on this specific node
- (IJSVGGradient*)strokeGradient
{ {
if (_strokeGradient == nil && _parentNode != nil) { IJSVGNode* node = nil;
return _parentNode.strokeGradient; IJSVGUnitType type = [self contentUnitsWithReferencingNode:&node];
} *bounds = node.parentNode.bounds;
return _strokeGradient; return type;
} }
// these are all recursive, so go up the chain - (IJSVGUnitType)contentUnitsWithReferencingNode:(IJSVGNode**)referencingNode
// if they dont exist on this specific node
- (IJSVGPattern*)strokePattern
{ {
if (_strokePattern == nil && _parentNode != nil) { if(_contentUnits == IJSVGUnitInherit && _parentNode != nil) {
return _parentNode.strokePattern; 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 @end
@@ -7,6 +7,7 @@
// //
#import <IJSVG/IJSVGNode.h> #import <IJSVG/IJSVGNode.h>
#import <IJSVG/IJSVGColorNode.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@class IJSVGGroup; @class IJSVGGroup;
@@ -29,7 +30,6 @@ typedef NS_ENUM(NSInteger, IJSVGPrimitivePathType) {
@property (nonatomic, assign) CGPoint lastControlPoint; @property (nonatomic, assign) CGPoint lastControlPoint;
@property (nonatomic, readonly) CGRect controlPointBoundingBox; @property (nonatomic, readonly) CGRect controlPointBoundingBox;
@property (nonatomic, readonly) CGRect pathBoundingBox; @property (nonatomic, readonly) CGRect pathBoundingBox;
@property (nonatomic, assign, readonly) BOOL isStroked;
- (void)close; - (void)close;
- (NSPoint)currentPoint; - (NSPoint)currentPoint;
+22 -6
View File
@@ -6,8 +6,7 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved. // Copyright (c) 2014 Curtis Hard. All rights reserved.
// //
#import "IJSVGGroup.h" #import <IJSVG/IJSVGPath.h>
#import "IJSVGPath.h"
@implementation IJSVGPath @implementation IJSVGPath
@@ -28,6 +27,11 @@
return self; return self;
} }
- (CGRect)bounds
{
return self.pathBoundingBox;
}
- (id)copyWithZone:(NSZone*)zone - (id)copyWithZone:(NSZone*)zone
{ {
IJSVGPath* node = [super copyWithZone:zone]; IJSVGPath* node = [super copyWithZone:zone];
@@ -65,11 +69,23 @@
CGPathCloseSubpath(_path); CGPathCloseSubpath(_path);
} }
- (BOOL)isStroked #pragma mark Traits
- (void)computeTraits
{ {
return (self.strokeColor != nil && self.strokeColor.alphaComponent != 0.f) || if(self.stroke != nil) {
self.strokePattern != nil || // by default we can just add this on
self.strokeGradient != nil; [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 @end
@@ -6,11 +6,12 @@
// Copyright © 2016 Curtis Hard. All rights reserved. // Copyright © 2016 Curtis Hard. All rights reserved.
// //
#import <IJSVG/IJSVGGroup.h>
#import <IJSVG/IJSVGImage.h> #import <IJSVG/IJSVGImage.h>
#import <IJSVG/IJSVGGroup.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface IJSVGPattern : IJSVGGroup { @interface IJSVGPattern : IJSVGGroup {
} }
@end @end
@@ -7,7 +7,19 @@
// //
#import "IJSVGPattern.h" #import "IJSVGPattern.h"
#import "IJSVGUnitRect.h"
@implementation IJSVGPattern @implementation IJSVGPattern
- (instancetype)init
{
if((self = [super init]) != nil) {
self.viewBox = nil;
self.viewBoxAlignment = IJSVGViewBoxAlignmentXMidYMid;
self.viewBoxMeetOrSlice = IJSVGViewBoxMeetOrSliceMeet;
}
return self;
}
@end @end
@@ -15,7 +15,8 @@
@property (nonatomic, retain) IJSVGUnitLength* cy; @property (nonatomic, retain) IJSVGUnitLength* cy;
@property (nonatomic, retain) IJSVGUnitLength* fx; @property (nonatomic, retain) IJSVGUnitLength* fx;
@property (nonatomic, retain) IJSVGUnitLength* fy; @property (nonatomic, retain) IJSVGUnitLength* fy;
@property (nonatomic, retain) IJSVGUnitLength* radius; @property (nonatomic, retain) IJSVGUnitLength* fr;
@property (nonatomic, retain) IJSVGUnitLength* r;
+ (NSGradient*)parseGradient:(NSXMLElement*)element + (NSGradient*)parseGradient:(NSXMLElement*)element
gradient:(IJSVGRadialGradient*)gradient; gradient:(IJSVGRadialGradient*)gradient;
@@ -6,8 +6,8 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved. // Copyright (c) 2014 Curtis Hard. All rights reserved.
// //
#import "IJSVGRadialGradient.h" #import <IJSVG/IJSVGRadialGradient.h>
#import "IJSVGParser.h" #import <IJSVG/IJSVGParser.h>
@implementation IJSVGRadialGradient @implementation IJSVGRadialGradient
@@ -17,7 +17,8 @@
(void)([_cy release]), _cy = nil; (void)([_cy release]), _cy = nil;
(void)([_fx release]), _fx = nil; (void)([_fx release]), _fx = nil;
(void)([_fy release]), _fy = nil; (void)([_fy release]), _fy = nil;
(void)([_radius release]), _radius = nil; (void)([_fr release]), _fr = nil;
(void)([_r release]), _r = nil;
[super dealloc]; [super dealloc];
} }
@@ -26,9 +27,10 @@
IJSVGRadialGradient* grad = [super copyWithZone:zone]; IJSVGRadialGradient* grad = [super copyWithZone:zone];
grad.fx = _fx; grad.fx = _fx;
grad.fy = _fy; grad.fy = _fy;
grad.fr = _fr;
grad.cx = _cx; grad.cx = _cx;
grad.cy = _cy; grad.cy = _cy;
grad.radius = _radius; grad.r = _r;
return grad; return grad;
} }
@@ -39,7 +41,7 @@
NSDictionary* kv = @{ NSDictionary* kv = @{
IJSVGAttributeCX : @"cx", IJSVGAttributeCX : @"cx",
IJSVGAttributeCY : @"cy", IJSVGAttributeCY : @"cy",
IJSVGAttributeR : @"radius" }; IJSVGAttributeR : @"r" };
for (NSString* key in kv.allKeys) { for (NSString* key in kv.allKeys) {
NSString* str = [element attributeForName:key].stringValue; NSString* str = [element attributeForName:key].stringValue;
@@ -55,6 +57,15 @@
forKey:kv[key]]; 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 // fx and fy are the same unless specified otherwise
gradient.fx = gradient.cx; gradient.fx = gradient.cx;
gradient.fy = gradient.cy; gradient.fy = gradient.cy;
@@ -67,7 +78,7 @@
} }
NSString* fy = [element attributeForName:IJSVGAttributeFY].stringValue; NSString* fy = [element attributeForName:IJSVGAttributeFY].stringValue;
if (fx != nil) { if (fy != nil) {
gradient.fy = [IJSVGUnitLength unitWithString:fy gradient.fy = [IJSVGUnitLength unitWithString:fy
fromUnitType:gradient.units]; fromUnitType:gradient.units];
} }
@@ -92,6 +103,7 @@
absoluteTransform:(CGAffineTransform)absoluteTransform absoluteTransform:(CGAffineTransform)absoluteTransform
viewPort:(CGRect)viewBox viewPort:(CGRect)viewBox
{ {
CGContextSaveGState(ctx);
BOOL inUserSpace = self.units == IJSVGUnitUserSpaceOnUse; BOOL inUserSpace = self.units == IJSVGUnitUserSpaceOnUse;
CGFloat radius = 0.f; CGFloat radius = 0.f;
CGPoint startPoint = CGPointZero; CGPoint startPoint = CGPointZero;
@@ -103,38 +115,53 @@
CGRect boundingBox = inUserSpace ? viewBox : objectRect; 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 // compute size based on percentages
CGFloat x = [_cx computeValue:CGRectGetWidth(boundingBox)]; CGFloat width = CGRectGetWidth(boundingBox);
CGFloat y = [_cy computeValue:CGRectGetHeight(boundingBox)]; CGFloat height = CGRectGetHeight(boundingBox);
startPoint = CGPointMake(x, y); CGFloat cx = [_cx computeValue:width];
CGFloat val = MIN(CGRectGetWidth(boundingBox), CGFloat cy = [_cy computeValue:height];
CGRectGetHeight(boundingBox)); startPoint = CGPointMake(cx, cy);
radius = [_radius computeValue:val]; CGFloat val = MIN(width, height);
radius = [_r computeValue:val];
CGFloat focalRadius = [_fr computeValue:val];
CGFloat ex = [_fx computeValue:CGRectGetWidth(boundingBox)]; CGFloat fx = [_fx computeValue:width];
CGFloat ey = [_fy computeValue:CGRectGetHeight(boundingBox)]; CGFloat fy = [_fy computeValue:height];
gradientEndPoint = CGPointMake(ex, ey); gradientEndPoint = CGPointMake(fx, fy);
gradientStartPoint = startPoint; gradientStartPoint = startPoint;
// transform if width or height is not equal - this can only // transform if width or height is not equal - this can only
// be done if we are using objectBoundingBox // be done if we are using objectBoundingBox
if (inUserSpace == NO && CGRectGetWidth(boundingBox) != CGRectGetHeight(boundingBox)) { if(inUserSpace == YES) {
CGAffineTransform tr = CGAffineTransformMakeTranslation(gradientStartPoint.x, CGFloat rad = 2.f * radius;
gradientStartPoint.y); CGRect rect = CGRectMake(startPoint.x, startPoint.y, rad, rad);
if (CGRectGetWidth(boundingBox) > CGRectGetHeight(boundingBox)) { rect = CGRectApplyAffineTransform(rect, selfTransform);
tr = CGAffineTransformScale(tr, CGRectGetWidth(boundingBox) / CGRectGetHeight(boundingBox), 1); 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 { } 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); invert = CGAffineTransformInvert(transform);
selfTransform = CGAffineTransformConcat(tr, selfTransform); 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 // transform the context
@@ -143,15 +170,16 @@
// draw the gradient // draw the gradient
CGGradientDrawingOptions options = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation; CGGradientDrawingOptions options = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
CGContextDrawRadialGradient(ctx, self.CGGradient, CGContextDrawRadialGradient(ctx, self.CGGradient,
gradientEndPoint, 0, gradientEndPoint, focalRadius,
gradientStartPoint, gradientStartPoint,
radius, options); radius, options);
CGContextRestoreGState(ctx);
#ifdef IJSVG_DEBUG_GRADIENTS //#ifdef IJSVG_DEBUG_GRADIENTS
[self _debugStart:gradientStartPoint // [self _debugStart:gradientStartPoint
end:gradientEndPoint // end:gradientEndPoint
context:ctx]; // context:ctx];
#endif //#endif
} }
@end @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/IJSVGError.h>
#import <IJSVG/IJSVGForeignObject.h> #import <IJSVG/IJSVGForeignObject.h>
#import <IJSVG/IJSVGGroup.h> #import <IJSVG/IJSVGGroup.h>
#import <IJSVG/IJSVGColorNode.h>
#import <IJSVG/IJSVGImage.h> #import <IJSVG/IJSVGImage.h>
#import <IJSVG/IJSVGLinearGradient.h> #import <IJSVG/IJSVGLinearGradient.h>
#import <IJSVG/IJSVGPath.h> #import <IJSVG/IJSVGPath.h>
@@ -26,6 +27,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
extern NSString* const IJSVGAttributeViewBox; extern NSString* const IJSVGAttributeViewBox;
extern NSString* const IJSVGAttributePreserveAspectRatio;
extern NSString* const IJSVGAttributeID; extern NSString* const IJSVGAttributeID;
extern NSString* const IJSVGAttributeClass; extern NSString* const IJSVGAttributeClass;
extern NSString* const IJSVGAttributeX; extern NSString* const IJSVGAttributeX;
@@ -40,6 +42,7 @@ extern NSString* const IJSVGAttributeFillOpacity;
extern NSString* const IJSVGAttributeClipPath; extern NSString* const IJSVGAttributeClipPath;
extern NSString* const IJSVGAttributeMask; extern NSString* const IJSVGAttributeMask;
extern NSString* const IJSVGAttributeGradientUnits; extern NSString* const IJSVGAttributeGradientUnits;
extern NSString* const IJSVGAttributePatternContentUnits;
extern NSString* const IJSVGAttributeMaskUnits; extern NSString* const IJSVGAttributeMaskUnits;
extern NSString* const IJSVGAttributeMaskContentUnits; extern NSString* const IJSVGAttributeMaskContentUnits;
extern NSString* const IJSVGAttributeTransform; extern NSString* const IJSVGAttributeTransform;
@@ -65,6 +68,7 @@ extern NSString* const IJSVGAttributeRY;
extern NSString* const IJSVGAttributeCX; extern NSString* const IJSVGAttributeCX;
extern NSString* const IJSVGAttributeCY; extern NSString* const IJSVGAttributeCY;
extern NSString* const IJSVGAttributeR; extern NSString* const IJSVGAttributeR;
extern NSString* const IJSVGAttributeFR;
extern NSString* const IJSVGAttributeFX; extern NSString* const IJSVGAttributeFX;
extern NSString* const IJSVGAttributeFY; extern NSString* const IJSVGAttributeFY;
extern NSString* const IJSVGAttributePoints; extern NSString* const IJSVGAttributePoints;
@@ -80,39 +84,28 @@ extern NSString* const IJSVGAttributeOverflow;
@protocol IJSVGParserDelegate <NSObject> @protocol IJSVGParserDelegate <NSObject>
@optional @optional
- (BOOL)svgParser:(IJSVGParser*)svg
shouldHandleForeignObject:(IJSVGForeignObject*)foreignObject;
- (void)svgParser:(IJSVGParser*)svg
handleForeignObject:(IJSVGForeignObject*)foreignObject
document:(NSXMLDocument*)document;
- (void)svgParser:(IJSVGParser*)svg - (void)svgParser:(IJSVGParser*)svg
foundSubSVG:(IJSVG*)subSVG foundSubSVG:(IJSVG*)subSVG
withSVGString:(NSString*)string; withSVGString:(NSString*)string;
@end @end
@interface IJSVGParser : IJSVGGroup { @interface IJSVGParser : NSObject {
@private @private
id<IJSVGParserDelegate> _delegate; id<IJSVGParserDelegate> _delegate;
NSXMLDocument* _document; NSXMLDocument* _document;
NSMutableArray<IJSVGPath*>* _glyphs;
IJSVGStyleSheet* _styleSheet;
NSMutableDictionary<NSString*, NSXMLElement*>* _defNodes;
NSMutableDictionary<NSString*, NSXMLElement*>* _baseDefNodes;
NSMutableArray<IJSVG*>* _svgs;
struct { struct {
unsigned int shouldHandleForeignObject : 1;
unsigned int handleForeignObject : 1;
unsigned int handleSubSVG : 1; unsigned int handleSubSVG : 1;
} _respondsTo; } _respondsTo;
IJSVGPathDataStream* _commandDataStream; IJSVGPathDataStream* _commandDataStream;
IJSVGStyleSheet* _styleSheet;
NSMapTable<IJSVGNode*, NSMutableDictionary<NSString*, NSXMLElement*>*>* _detachedElements;
} }
@property (nonatomic, readonly) NSRect viewBox; @property (nonatomic, retain, readonly) IJSVGRootNode* rootNode;
@property (nonatomic, readonly) IJSVGUnitSize* intrinsicSize;
+ (BOOL)isDataSVG:(NSData*)data; + (BOOL)isDataSVG:(NSData*)data;
@@ -129,9 +122,5 @@ extern NSString* const IJSVGAttributeOverflow;
+ (IJSVGParser*)groupForFileURL:(NSURL*)aURL + (IJSVGParser*)groupForFileURL:(NSURL*)aURL
error:(NSError**)error error:(NSError**)error
delegate:(id<IJSVGParserDelegate>)delegate; delegate:(id<IJSVGParserDelegate>)delegate;
- (NSSize)size;
- (BOOL)isFont;
- (NSArray*)glyphs;
- (NSArray<IJSVG*>*)subSVGs:(BOOL)recursive;
@end @end
File diff suppressed because it is too large Load Diff
@@ -11,13 +11,20 @@
#import <QuartzCore/QuartzCore.h> #import <QuartzCore/QuartzCore.h>
@class IJSVGLayer; @class IJSVGLayer;
@class IJSVGRootLayer;
@class IJSVGRootNode;
@interface IJSVGLayerTree : NSObject { @interface IJSVGLayerTree : NSObject {
@private
NSMutableArray<NSValue*>* _viewPortStack;
} }
@property (nonatomic, assign) CGRect viewBox; @property (nonatomic, assign) CGRect viewBox;
@property (nonatomic, assign) CGFloat backingScale;
@property (nonatomic, retain) IJSVGRenderingStyle* style; @property (nonatomic, retain) IJSVGRenderingStyle* style;
- (IJSVGLayer*)layerForNode:(IJSVGNode*)node; - (id)initWithViewPortRect:(CGRect)viewPort
backingScale:(CGFloat)scale;
- (IJSVGRootLayer*)rootLayerForRootNode:(IJSVGRootNode*)rootNode;
@end @end
File diff suppressed because it is too large Load Diff
@@ -41,11 +41,11 @@ IJSVGNode * IJSVGStyleSheetPreviousNode(IJSVGNode * node)
IJSVGGroup * group = (IJSVGGroup *)node.parentNode; IJSVGGroup * group = (IJSVGGroup *)node.parentNode;
if([group isKindOfClass:[IJSVGGroup class]] == NO) if([group isKindOfClass:[IJSVGGroup class]] == NO)
return nil; return nil;
NSInteger currentIndex = [group.childNodes indexOfObject:node]; NSInteger currentIndex = [group.children indexOfObject:node];
if(currentIndex == 0) { if(currentIndex == 0) {
return nil; return nil;
} }
return group.childNodes[currentIndex-1]; return group.children[currentIndex-1];
}; };
IJSVGNode * IJSVGStyleSheetNextNode(IJSVGNode * node) IJSVGNode * IJSVGStyleSheetNextNode(IJSVGNode * node)
@@ -54,11 +54,11 @@ IJSVGNode * IJSVGStyleSheetNextNode(IJSVGNode * node)
if([group isKindOfClass:[IJSVGGroup class]] == NO) { if([group isKindOfClass:[IJSVGGroup class]] == NO) {
return nil; return nil;
} }
NSInteger currentIndex = [group.childNodes indexOfObject:node]; NSInteger currentIndex = [group.children indexOfObject:node];
if(currentIndex == group.childNodes.count-1) { if(currentIndex == group.children.count-1) {
return nil; return nil;
} }
return group.childNodes[currentIndex+1]; return group.children[currentIndex+1];
}; };
IJSVGStyleSheetSelectorRaw * IJSVGStyleSheetPreviousSelector(IJSVGStyleSheetSelectorRaw * aSelector, NSArray * _rawSelectors) IJSVGStyleSheetSelectorRaw * IJSVGStyleSheetPreviousSelector(IJSVGStyleSheetSelectorRaw * aSelector, NSArray * _rawSelectors)
@@ -147,7 +147,7 @@ BOOL IJSVGStyleSheetMatchSelector(IJSVGNode * node, IJSVGStyleSheetSelectorRaw *
} }
// grab the children // grab the children
NSArray * nodes = parentNode.childNodes; NSArray * nodes = parentNode.children;
NSInteger index = [nodes indexOfObject:aNode]; NSInteger index = [nodes indexOfObject:aNode];
// doesnt contain the child // doesnt contain the child
@@ -226,7 +226,7 @@ BOOL IJSVGStyleSheetMatchSelector(IJSVGNode * node, IJSVGStyleSheetSelectorRaw *
// matches the next selector and... contains the node in question // matches the next selector and... contains the node in question
IJSVGStyleSheetSelectorRaw * s = IJSVGStyleSheetNextSelector(aSelector,_rawSelectors); IJSVGStyleSheetSelectorRaw * s = IJSVGStyleSheetNextSelector(aSelector,_rawSelectors);
if(IJSVGStyleSheetMatchSelector(parentNode, s) && if(IJSVGStyleSheetMatchSelector(parentNode, s) &&
[parentNode.childNodes containsObject:aNode]) { [parentNode.children containsObject:aNode]) {
// set the new starting selector and node // set the new starting selector and node
aSelector = s; aSelector = s;
aNode = parentNode; aNode = parentNode;
@@ -35,6 +35,7 @@ typedef NS_ENUM(NSInteger, IJSVGTransformCommand) {
@property (nonatomic, assign) NSInteger sort; @property (nonatomic, assign) NSInteger sort;
void IJSVGApplyTransform(NSArray<IJSVGTransform*>* transforms, IJSVGTransformApplyBlock block); void IJSVGApplyTransform(NSArray<IJSVGTransform*>* transforms, IJSVGTransformApplyBlock block);
BOOL IJSVGAffineTransformScalesAndTranslates(CGAffineTransform affineTransform);
CGAffineTransform IJSVGConcatTransforms(NSArray<IJSVGTransform*>* transforms); CGAffineTransform IJSVGConcatTransforms(NSArray<IJSVGTransform*>* transforms);
NSString* IJSVGTransformAttributeString(CGAffineTransform transform); NSString* IJSVGTransformAttributeString(CGAffineTransform transform);
@@ -47,6 +48,8 @@ NSString* IJSVGTransformAttributeString(CGAffineTransform transform);
+ (NSString*)affineTransformToSVGMatrixString:(CGAffineTransform)affineTransform; + (NSString*)affineTransformToSVGMatrixString:(CGAffineTransform)affineTransform;
+ (NSString*)affineTransformToSVGMatrixString:(CGAffineTransform)transform + (NSString*)affineTransformToSVGMatrixString:(CGAffineTransform)transform
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions; floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions;
- (void)applyBounds:(CGRect)bounds
withContentUnits:(IJSVGUnitType)contentUnits;
- (CGAffineTransform)CGAffineTransform; - (CGAffineTransform)CGAffineTransform;
- (CGAffineTransform)CGAffineTransformWithModifier:(IJSVGTransformParameterModifier)modifier; - (CGAffineTransform)CGAffineTransformWithModifier:(IJSVGTransformParameterModifier)modifier;
- (CGAffineTransform)stackIdentity:(CGAffineTransform)identity; - (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 + (IJSVGTransform*)transformByTranslatingX:(CGFloat)x
y:(CGFloat)y y:(CGFloat)y
{ {
@@ -198,6 +208,26 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform*>* transforms, IJSVGTransformApp
return transforms; 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 - (CGAffineTransform)CGAffineTransform
{ {
return [self stackIdentity:CGAffineTransformIdentity]; return [self stackIdentity:CGAffineTransformIdentity];
@@ -605,7 +635,7 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform*>* transforms, IJSVGTransformApp
- (NSString*)description - (NSString*)description
{ {
return [NSString stringWithFormat:@"%@ %@", [super description], return [NSString stringWithFormat:@"%@ %@", [super description],
[self.class affineTransformToSVGMatrixString:self.CGAffineTransform]]; [self.class affineTransformToSVGTransformComponentString:self.CGAffineTransform]];
} }
@end @end
@@ -30,13 +30,15 @@ typedef NS_ENUM(NSInteger, IJSVGUnitType) {
IJSVGUnitInherit IJSVGUnitInherit
}; };
@interface IJSVGUnitLength : NSObject @interface IJSVGUnitLength : NSObject <NSCopying>
@property (nonatomic, assign) IJSVGUnitLengthType type; @property (nonatomic, assign) IJSVGUnitLengthType type;
@property (nonatomic, assign) IJSVGUnitLengthType originalType; @property (nonatomic, assign) IJSVGUnitLengthType originalType;
@property (nonatomic, assign) CGFloat value; @property (nonatomic, assign) CGFloat value;
@property (nonatomic, assign) BOOL inherit; @property (nonatomic, assign) BOOL inherit;
+ (IJSVGUnitLength*)zeroUnitLength;
+ (IJSVGUnitLength*)unitWithFloat:(CGFloat)number; + (IJSVGUnitLength*)unitWithFloat:(CGFloat)number;
+ (IJSVGUnitLength*)unitWithFloat:(CGFloat)number + (IJSVGUnitLength*)unitWithFloat:(CGFloat)number
type:(IJSVGUnitLengthType)type; type:(IJSVGUnitLengthType)type;
@@ -47,6 +49,8 @@ typedef NS_ENUM(NSInteger, IJSVGUnitType) {
+ (IJSVGUnitLength*)unitWithString:(NSString*)string + (IJSVGUnitLength*)unitWithString:(NSString*)string
fromUnitType:(IJSVGUnitType)units; fromUnitType:(IJSVGUnitType)units;
- (IJSVGUnitLength*)lengthWithUnitType:(IJSVGUnitLengthType)type;
- (IJSVGUnitLength*)lengthByMatchingPercentage;
- (CGFloat)valueAsPercentage; - (CGFloat)valueAsPercentage;
- (CGFloat)computeValue:(CGFloat)anotherValue; - (CGFloat)computeValue:(CGFloat)anotherValue;
- (NSString*)stringValue; - (NSString*)stringValue;
@@ -12,6 +12,12 @@
@implementation IJSVGUnitLength @implementation IJSVGUnitLength
+ (IJSVGUnitLength*)zeroUnitLength
{
return [self unitWithFloat:0.f
type:IJSVGUnitLengthTypeNumber];
}
+ (IJSVGUnitLength*)unitWithFloat:(CGFloat)number + (IJSVGUnitLength*)unitWithFloat:(CGFloat)number
{ {
IJSVGUnitLength* unit = [[[self alloc] init] autorelease]; IJSVGUnitLength* unit = [[[self alloc] init] autorelease];
@@ -192,6 +198,32 @@
return unit; 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 - (CGFloat)computeValue:(CGFloat)anotherValue
{ {
if (self.type == IJSVGUnitLengthTypePercentage) { if (self.type == IJSVGUnitLengthTypePercentage) {
@@ -9,9 +9,16 @@
#import <IJSVG/IJSVGUnitLength.h> #import <IJSVG/IJSVGUnitLength.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface IJSVGUnitPoint : NSObject @interface IJSVGUnitPoint : NSObject <NSCopying>
@property (nonatomic, retain) IJSVGUnitLength* x; @property (nonatomic, retain) IJSVGUnitLength* x;
@property (nonatomic, retain) IJSVGUnitLength* y; @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 @end
@@ -26,4 +26,28 @@
return point; 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 @end
@@ -10,12 +10,24 @@
#import <IJSVG/IJSVGUnitSize.h> #import <IJSVG/IJSVGUnitSize.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface IJSVGUnitRect : NSObject @interface IJSVGUnitRect : NSObject <NSCopying>
@property (nonatomic, retain) IJSVGUnitSize* size; @property (nonatomic, retain) IJSVGUnitSize* size;
@property (nonatomic, retain) IJSVGUnitPoint* origin; @property (nonatomic, retain) IJSVGUnitPoint* origin;
@property (nonatomic, readonly) BOOL isZeroRect;
@property (nonatomic, readonly) CGRect value;
+ (IJSVGUnitRect*)rectWithCGRect:(CGRect)rect;
+ (IJSVGUnitRect*)rectWithOrigin:(IJSVGUnitPoint*)origin + (IJSVGUnitRect*)rectWithOrigin:(IJSVGUnitPoint*)origin
size:(IJSVGUnitSize*)size; 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 @end
@@ -26,4 +26,65 @@
return rect; 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 @end
@@ -9,12 +9,16 @@
#import <IJSVG/IJSVGUnitLength.h> #import <IJSVG/IJSVGUnitLength.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface IJSVGUnitSize : NSObject @interface IJSVGUnitSize : NSObject <NSCopying>
@property (nonatomic, retain) IJSVGUnitLength* width; @property (nonatomic, retain) IJSVGUnitLength* width;
@property (nonatomic, retain) IJSVGUnitLength* height; @property (nonatomic, retain) IJSVGUnitLength* height;
@property (nonatomic, readonly) CGSize value;
+ (IJSVGUnitSize*)sizeWithWidth:(IJSVGUnitLength*)width + (IJSVGUnitSize*)sizeWithWidth:(IJSVGUnitLength*)width
height:(IJSVGUnitLength*)height; height:(IJSVGUnitLength*)height;
- (void)convertUnitsToLengthType:(IJSVGUnitLengthType)lengthType;
- (CGSize)computeValue:(CGSize)size;
@end @end
@@ -26,4 +26,29 @@
return size; 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 @end
@@ -10,6 +10,7 @@
#import <IJSVG/IJSVGGradientUnitLength.h> #import <IJSVG/IJSVGGradientUnitLength.h>
#import <IJSVG/IJSVGStringAdditions.h> #import <IJSVG/IJSVGStringAdditions.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@@ -28,6 +29,7 @@ char* IJSVGTimmedCharBufferCreate(const char* buffer);
void IJSVGTrimCharBuffer(char* buffer); void IJSVGTrimCharBuffer(char* buffer);
void IJSVGCharBufferToLower(char* buffer); void IJSVGCharBufferToLower(char* buffer);
size_t IJSVGCharBufferHash(char* buffer); size_t IJSVGCharBufferHash(char* buffer);
CGPoint IJSVGPathGetLastQuadraticCommandPoint(CGPathRef path);
IJSVGFloatingPointOptions IJSVGFloatingPointOptionsDefault(void); IJSVGFloatingPointOptions IJSVGFloatingPointOptionsDefault(void);
IJSVGFloatingPointOptions IJSVGFloatingPointOptionsMake(BOOL round, int precision); IJSVGFloatingPointOptions IJSVGFloatingPointOptionsMake(BOOL round, int precision);
@@ -76,5 +78,10 @@ BOOL IJSVGIsSVGLayer(CALayer* layer);
weight:(CGFloat*)weight; weight:(CGFloat*)weight;
+ (CGPathRef)newFlippedCGPath:(CGPathRef)path; + (CGPathRef)newFlippedCGPath:(CGPathRef)path;
+ (CAShapeLayerLineJoin)CGLineJoinForJoinStyle:(IJSVGLineJoinStyle)joinStyle;
+ (CAShapeLayerLineCap)CGLineCapForCapStyle:(IJSVGLineCapStyle)capStyle;
+ (CAShapeLayerFillRule)CGFillRuleForWindingRule:(IJSVGWindingRule)rule;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
@@ -192,6 +192,27 @@ BOOL IJSVGIsLegalCommandCharacter(unichar aChar)
return NO; 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) BOOL IJSVGIsSVGLayer(CALayer* layer)
{ {
return [layer isKindOfClass:IJSVGLayer.class] || return [layer isKindOfClass:IJSVGLayer.class] ||
@@ -556,4 +577,50 @@ CGFloat degrees_to_radians(CGFloat degrees)
return transformPath; 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 @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 = { objects = {
/* Begin PBXBuildFile section */ /* 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 */; }; 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 */; }; 59069A2B22D0EE0E004DDEA5 /* test (1).svg in Resources */ = {isa = PBXBuildFile; fileRef = 59069A2A22D0EE0E004DDEA5 /* test (1).svg */; };
590C87EB201F9888004A1554 /* json.svg in Resources */ = {isa = PBXBuildFile; fileRef = 590C87EA201F9888004A1554 /* json.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 */; }; 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 */; }; 590C87F4201FC9E4004A1554 /* radialgradient2.svg in Resources */ = {isa = PBXBuildFile; fileRef = 590C87F3201FC9E3004A1554 /* radialgradient2.svg */; };
590C87F6201FD0D4004A1554 /* car.svg in Resources */ = {isa = PBXBuildFile; fileRef = 590C87F5201FD0D4004A1554 /* car.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 */; }; 59265CE81C4F840400F333F0 /* css.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59265CE71C4F840400F333F0 /* css.svg */; };
59265CEB1C4F843E00F333F0 /* SVGExampleView6.m in Sources */ = {isa = PBXBuildFile; fileRef = 59265CEA1C4F843E00F333F0 /* SVGExampleView6.m */; }; 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 */; }; 59459CEC19B906FE00CE493B /* clipped.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59459CEB19B906FE00CE493B /* clipped.svg */; };
59459CEF19B9074F00CE493B /* SVGExampleView4.m in Sources */ = {isa = PBXBuildFile; fileRef = 59459CEE19B9074F00CE493B /* SVGExampleView4.m */; }; 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 */; }; 5956657D19B62F4600D805FF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956657C19B62F4600D805FF /* main.m */; };
5956658019B62F4600D805FF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956657F19B62F4600D805FF /* AppDelegate.m */; }; 5956658019B62F4600D805FF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956657F19B62F4600D805FF /* AppDelegate.m */; };
5956658219B62F4600D805FF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5956658119B62F4600D805FF /* Images.xcassets */; }; 5956658219B62F4600D805FF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5956658119B62F4600D805FF /* Images.xcassets */; };
5956658519B62F4600D805FF /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5956658319B62F4600D805FF /* MainMenu.xib */; }; 5956658519B62F4600D805FF /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5956658319B62F4600D805FF /* MainMenu.xib */; };
5956659119B62F4700D805FF /* IJSVGExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956659019B62F4700D805FF /* IJSVGExampleTests.m */; }; 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 */; }; 595665DE19B6309C00D805FF /* test.svg in Resources */ = {isa = PBXBuildFile; fileRef = 595665DD19B6309C00D805FF /* test.svg */; };
595665E119B630B600D805FF /* SVGView.m in Sources */ = {isa = PBXBuildFile; fileRef = 595665E019B630B600D805FF /* SVGView.m */; }; 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 */; }; 597AC83322CFD0FC007C0E42 /* home.svg in Resources */ = {isa = PBXBuildFile; fileRef = 597AC83222CFD0FC007C0E42 /* home.svg */; };
5986308719BA104800CF15EA /* linecap.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5986308619BA104800CF15EA /* linecap.svg */; }; 5986308719BA104800CF15EA /* linecap.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5986308619BA104800CF15EA /* linecap.svg */; };
5986308A19BA106D00CF15EA /* SVGExampleView5.m in Sources */ = {isa = PBXBuildFile; fileRef = 5986308919BA106D00CF15EA /* SVGExampleView5.m */; }; 5986308A19BA106D00CF15EA /* SVGExampleView5.m in Sources */ = {isa = PBXBuildFile; fileRef = 5986308919BA106D00CF15EA /* SVGExampleView5.m */; };
5986308C19BA180E00CF15EA /* dashed.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5986308B19BA180E00CF15EA /* dashed.svg */; }; 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 */; }; 5991A2A9201E30E600913E3B /* gradients.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5991A2A8201E30E600913E3B /* gradients.svg */; };
5991A2AB201E310200913E3B /* heart.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5991A2AA201E310200913E3B /* heart.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 */; }; 59A11E6C19B89CEA00E44498 /* SVGExampleView1.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A11E6B19B89CEA00E44498 /* SVGExampleView1.m */; };
59A11E6F19B89D2000E44498 /* SVGExampleView2.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A11E6E19B89D2000E44498 /* SVGExampleView2.m */; }; 59A11E6F19B89D2000E44498 /* SVGExampleView2.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A11E6E19B89D2000E44498 /* SVGExampleView2.m */; };
59A11E7219B89D6600E44498 /* SVGExampleView3.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A11E7119B89D6600E44498 /* SVGExampleView3.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 */; }; 59B93C6D19B7D1840063E823 /* paperplane.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59B93C6C19B7D1840063E823 /* paperplane.svg */; };
59B93C6F19B7D32C0063E823 /* products.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59B93C6E19B7D32C0063E823 /* products.svg */; }; 59B93C6F19B7D32C0063E823 /* products.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59B93C6E19B7D32C0063E823 /* products.svg */; };
59D1E3A0202279CA00C54672 /* Group.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59D1E39F202279CA00C54672 /* Group.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 */; }; 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 */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@@ -104,11 +51,36 @@
remoteGlobalIDString = 5956657619B62F4600D805FF; remoteGlobalIDString = 5956657619B62F4600D805FF;
remoteInfo = IJSVGExample; 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 */ /* 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 */ /* 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 5934D504280C933300BEF20F /* IJSVGExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IJSVGExample.entitlements; 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>"; };
59459CEB19B906FE00CE493B /* clipped.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = clipped.svg; 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>"; }; 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>"; }; 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; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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 */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@@ -269,6 +135,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
59FB54BE280B03E600D148FA /* IJSVG.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -285,9 +152,11 @@
5956656E19B62F4600D805FF = { 5956656E19B62F4600D805FF = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
59FB54B3280B038200D148FA /* IJSVG.xcodeproj */,
5956657919B62F4600D805FF /* IJSVGExample */, 5956657919B62F4600D805FF /* IJSVGExample */,
5956658D19B62F4700D805FF /* IJSVGExampleTests */, 5956658D19B62F4700D805FF /* IJSVGExampleTests */,
5956657819B62F4600D805FF /* Products */, 5956657819B62F4600D805FF /* Products */,
59FB54BD280B03E600D148FA /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@@ -303,7 +172,7 @@
5956657919B62F4600D805FF /* IJSVGExample */ = { 5956657919B62F4600D805FF /* IJSVGExample */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
5956659B19B62FA400D805FF /* IJSVG */, 5934D504280C933300BEF20F /* IJSVGExample.entitlements */,
5956657E19B62F4600D805FF /* AppDelegate.h */, 5956657E19B62F4600D805FF /* AppDelegate.h */,
5956657F19B62F4600D805FF /* AppDelegate.m */, 5956657F19B62F4600D805FF /* AppDelegate.m */,
5956658119B62F4600D805FF /* Images.xcassets */, 5956658119B62F4600D805FF /* Images.xcassets */,
@@ -374,130 +243,19 @@
name = "Supporting Files"; name = "Supporting Files";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
5956659B19B62FA400D805FF /* IJSVG */ = { 59FB54B4280B038200D148FA /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
59E2641A19BA240D008A6FDB /* source */, 59FB54B8280B038200D148FA /* IJSVG.framework */,
595665C619B6302600D805FF /* README.md */,
); );
name = IJSVG; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
59E2641A19BA240D008A6FDB /* source */ = { 59FB54BD280B03E600D148FA /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( 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; name = Frameworks;
path = ../../source;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
/* End PBXGroup section */ /* End PBXGroup section */
@@ -510,10 +268,12 @@
5956657319B62F4600D805FF /* Sources */, 5956657319B62F4600D805FF /* Sources */,
5956657419B62F4600D805FF /* Frameworks */, 5956657419B62F4600D805FF /* Frameworks */,
5956657519B62F4600D805FF /* Resources */, 5956657519B62F4600D805FF /* Resources */,
59FB54BF280B03EE00D148FA /* CopyFiles */,
); );
buildRules = ( buildRules = (
); );
dependencies = ( dependencies = (
59FB54BC280B03E100D148FA /* PBXTargetDependency */,
); );
name = IJSVGExample; name = IJSVGExample;
productName = IJSVGExample; productName = IJSVGExample;
@@ -568,6 +328,12 @@
mainGroup = 5956656E19B62F4600D805FF; mainGroup = 5956656E19B62F4600D805FF;
productRefGroup = 5956657819B62F4600D805FF /* Products */; productRefGroup = 5956657819B62F4600D805FF /* Products */;
projectDirPath = ""; projectDirPath = "";
projectReferences = (
{
ProductGroup = 59FB54B4280B038200D148FA /* Products */;
ProjectRef = 59FB54B3280B038200D148FA /* IJSVG.xcodeproj */;
},
);
projectRoot = ""; projectRoot = "";
targets = ( targets = (
5956657619B62F4600D805FF /* IJSVGExample */, 5956657619B62F4600D805FF /* IJSVGExample */,
@@ -576,6 +342,16 @@
}; };
/* End PBXProject section */ /* 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 */ /* Begin PBXResourcesBuildPhase section */
5956657519B62F4600D805FF /* Resources */ = { 5956657519B62F4600D805FF /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
@@ -620,70 +396,15 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( 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 */, 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 */, 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 */, 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 */, 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 */, 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 */, 59A11E7219B89D6600E44498 /* SVGExampleView3.m in Sources */,
59E0F5ED1E29964700F757F7 /* IJSVGUnitLength.m in Sources */,
5956657D19B62F4600D805FF /* main.m in Sources */, 5956657D19B62F4600D805FF /* main.m in Sources */,
59EA311722CF395400DAB3B7 /* IJSVGRendering.m in Sources */,
59A11E6F19B89D2000E44498 /* SVGExampleView2.m in Sources */, 59A11E6F19B89D2000E44498 /* SVGExampleView2.m in Sources */,
5948DED51BB2BFE5004156FF /* IJSVGFontConverter.m in Sources */,
59E2646319BA240D008A6FDB /* IJSVGGroup.m in Sources */,
59459CEF19B9074F00CE493B /* SVGExampleView4.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; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -703,6 +424,11 @@
target = 5956657619B62F4600D805FF /* IJSVGExample */; target = 5956657619B62F4600D805FF /* IJSVGExample */;
targetProxy = 5956658B19B62F4700D805FF /* PBXContainerItemProxy */; targetProxy = 5956658B19B62F4700D805FF /* PBXContainerItemProxy */;
}; };
59FB54BC280B03E100D148FA /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = IJSVG;
targetProxy = 59FB54BB280B03E100D148FA /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */ /* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */ /* Begin PBXVariantGroup section */
@@ -799,6 +525,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = IJSVGExample/IJSVGExample.entitlements;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = IJSVGExample/Info.plist; INFOPLIST_FILE = IJSVGExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
@@ -810,6 +537,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = IJSVGExample/IJSVGExample.entitlements;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = IJSVGExample/Info.plist; INFOPLIST_FILE = IJSVGExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
@@ -3,4 +3,38 @@
uuid = "21141E92-29FD-4CF6-AB04-0D4E4FD9A4AC" uuid = "21141E92-29FD-4CF6-AB04-0D4E4FD9A4AC"
type = "1" type = "1"
version = "2.0"> 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> </Bucket>
@@ -40,8 +40,16 @@
buildConfiguration = "Debug" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5956657619B62F4600D805FF"
BuildableName = "IJSVGExample.app"
BlueprintName = "IJSVGExample"
ReferencedContainer = "container:IJSVGExample.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables> <Testables>
<TestableReference <TestableReference
skipped = "NO"> skipped = "NO">
@@ -54,23 +62,11 @@
</BuildableReference> </BuildableReference>
</TestableReference> </TestableReference>
</Testables> </Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5956657619B62F4600D805FF"
BuildableName = "IJSVGExample.app"
BlueprintName = "IJSVGExample"
ReferencedContainer = "container:IJSVGExample.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Debug" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0" launchStyle = "0"
useCustomWorkingDirectory = "NO" useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"
@@ -87,8 +83,13 @@
ReferencedContainer = "container:IJSVGExample.xcodeproj"> ReferencedContainer = "container:IJSVGExample.xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
<AdditionalOptions> <EnvironmentVariables>
</AdditionalOptions> <EnvironmentVariable
key = "CG_CONTEXT_SHOW_BACKTRACE"
value = "1"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction> </LaunchAction>
<ProfileAction <ProfileAction
buildConfiguration = "Release" 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>
+2
View File
@@ -24,6 +24,8 @@
<string>1</string> <string>1</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string> <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSAppTransportSecurity</key>
<dict/>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2014 Curtis Hard. All rights reserved.</string> <string>Copyright © 2014 Curtis Hard. All rights reserved.</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
+1 -1
View File
@@ -7,7 +7,7 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "IJSVG.h" #import <IJSVG/IJSVG.h>
@interface SVGView : NSView { @interface SVGView : NSView {
+3 -4
View File
@@ -7,7 +7,6 @@
// //
#import "SVGView.h" #import "SVGView.h"
#import "IJSVGExporter.h"
@implementation SVGView @implementation SVGView
@@ -21,8 +20,8 @@
{ {
if( ( self = [super initWithFrame:frameRect] ) != nil ) if( ( self = [super initWithFrame:frameRect] ) != nil )
{ {
svg = [self svg]; svg = [self svg].retain;
svg.renderQuality = IJSVGRenderQualityFullResolution; svg.renderQuality = kIJSVGRenderQualityFullResolution;
svg.renderingBackingScaleHelper = ^{ svg.renderingBackingScaleHelper = ^{
return self.window.backingScaleFactor; return self.window.backingScaleFactor;
}; };
@@ -32,7 +31,7 @@
- (IJSVG *)svg - (IJSVG *)svg
{ {
return [IJSVG svgNamed:@"test (1)"]; return [IJSVG svgNamed:@"AJ_Digital_Camera"];
} }
- (void)drawRect:(NSRect)dirtyRect - (void)drawRect:(NSRect)dirtyRect
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 522 KiB

After

Width:  |  Height:  |  Size: 992 B