Compare commits

...

52 Commits

Author SHA1 Message Date
Curtis Hard 849807d3c5 Updated build number 2020-01-05 17:11:41 +00:00
Curtis Hard eeb03bd89c Fixes exporter being wrong if the viewbox is not zero 2020-01-02 14:16:17 +00:00
Curtis Hard fdc0859e3f Faster parsing still 2020-01-01 22:06:29 +00:00
Curtis Hard e2a7f51507 Fixes 2020-01-01 17:48:15 +00:00
Curtis Hard ab69ed94dc Formatting 2019-12-29 20:50:44 +00:00
Curtis Hard c5be83f57f Code cleanup 2019-12-28 15:48:43 +00:00
Curtis Hard ed00aca06e Refactor 2019-12-27 16:48:12 +00:00
Curtis Hard f51fda5f1e Removed cache
- also fixes center if no scale was applied
2019-12-27 15:01:20 +00:00
Curtis Hard dd655053ca Finally fixes memory leak
- due to this being fixed, we can also get rid of the transaction lock
2019-12-26 20:10:47 +00:00
Curtis Hard 8c89627f74 Just use matrix, attributes are a pain in the butt 2019-12-26 16:08:14 +00:00
Curtis Hard eb1d27decd Much better path compression and float rewriting for exporting 2019-12-26 13:49:41 +00:00
Curtis Hard e6141d7a0f Fixes a long time ago bug with transforms with matrix converting to attribute strings 2019-12-25 21:05:56 +00:00
Curtis Hard 3b7ad40794 Vey strange... 2019-12-25 18:40:50 +00:00
Curtis Hard 674d17863f Fixes memory overflow issues
- also added centering for exported SVG’s as an option
2019-12-25 18:19:28 +00:00
Curtis Hard a59072fa1d Refactor 2019-12-25 13:53:42 +00:00
Curtis Hard 910b90cd4e More perf stuff 2019-12-25 13:45:13 +00:00
Curtis Hard bb3b9c5378 More improvements 2019-12-25 11:58:10 +00:00
Curtis Hard 6d10b172e7 Increases again 2019-12-24 14:47:47 +00:00
Curtis Hard c6e59a9280 More perf increases 2019-12-24 09:27:06 +00:00
Curtis Hard df5b3219ca Refactor of naming 2019-12-23 21:59:19 +00:00
Curtis Hard 2c1ae8d0f3 Credit where its due 2019-12-23 21:40:02 +00:00
Curtis Hard 7ba939aabf This is insanely fast 2019-12-23 20:48:12 +00:00
Curtis Hard 24e097fedf Faster again! 2019-12-23 20:30:05 +00:00
Curtis Hard 025ac84958 Refactor of command parsing 2019-12-23 19:37:56 +00:00
Curtis Hard ac9ccdda25 Refactor 2019-12-23 16:17:47 +00:00
Curtis Hard 14641ddd60 More goodies 2019-12-23 15:40:41 +00:00
Curtis Hard 5f32d03744 Intiial commit 2019-12-23 14:24:49 +00:00
Curtis Hard af086622b1 Faster implementation of transaction 2019-12-22 22:19:20 +00:00
Curtis Hard 79187326bc Added CGImageRef method 2019-12-21 13:23:52 +00:00
Curtis Hard ee570eb77f Fixes scale being incorrect 2019-12-20 08:36:12 +00:00
Curtis Hard d8e1ce8d70 This is much more performant then using nsimage lockFocus 2019-12-19 22:32:55 +00:00
Curtis Hard a900e2dc50 Resorted this list as its actually faster, basically stick the commonly used commands first 2019-12-17 21:48:52 +00:00
Curtis Hard 21f97babec Refactor of contsant names 2019-12-12 11:02:49 +00:00
Curtis Hard 0273a491de Refactor of path - uses less memory and makes more sense 2019-12-12 10:51:20 +00:00
Curtis Hard 488a0c3654 Update all things! 2019-12-12 08:09:08 +00:00
Curtis Hard 7f7321e6a7 Merge branch 'feature/primitiveExportTypes' 2019-12-12 08:07:05 +00:00
Curtis Hard d0878c9f1b Added convenience method in 2019-12-11 15:47:12 +00:00
Curtis Hard cd135ce271 Refactor and more performant string passing 2019-12-11 13:22:16 +00:00
Curtis Hard b369891e96 Added sequences to float parsing 2019-12-10 22:25:21 +00:00
Curtis Hard cde99fc501 Fixes memory leak 2019-12-06 12:03:44 +00:00
Curtis Hard efc5f139f6 Formatting 2019-12-06 08:26:03 +00:00
Curtis Hard f1c62ed828 Fixes a few things 2019-12-05 21:07:40 +00:00
Curtis Hard d66332ad07 Added is main thread check to transaction 2019-12-05 11:12:45 +00:00
Curtis Hard f2363769bf replaced calls with prefix 2019-12-04 12:58:08 +00:00
Curtis Hard ca1f0d9bf3 Performance increases and memory enhancements 2019-12-04 12:52:58 +00:00
Curtis Hard 8b7fc3171d More goodies 2019-12-04 08:59:55 +00:00
Curtis Hard 38df2094c9 Refactor and moving of groups 2019-12-04 08:59:46 +00:00
Curtis Hard 2355e86ed7 Fixes memory leak 2019-12-03 22:43:25 +00:00
Curtis Hard 192a9259fe Fixes performance here 2019-12-03 22:38:20 +00:00
Curtis Hard 2a9eb3cdc5 Added support for transparent 2019-12-03 14:26:11 +00:00
Curtis Hard 6ed4e3fb8e Export primitive shapes if they were that on import 2019-12-03 14:17:31 +00:00
Curtis Hard f6e1f1494e Initial stuff 2019-12-03 09:22:46 +00:00
124 changed files with 1789 additions and 1504 deletions
+312 -222
View File
@@ -11,6 +11,8 @@
594CF561238FF46C009B251B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF560238FF46C009B251B /* Foundation.framework */; };
594CF563238FF473009B251B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF562238FF473009B251B /* QuartzCore.framework */; };
599EB4D3238FF570004CB6BC /* libobjc.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 599EB4D2238FF535004CB6BC /* libobjc.tbd */; };
59E7CFAF23B148600077D599 /* IJSVGCommandParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 59E7CFAD23B148600077D599 /* IJSVGCommandParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
59E7CFB023B148600077D599 /* IJSVGCommandParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E7CFAE23B148600077D599 /* IJSVGCommandParser.m */; };
59EB75D623905F7300F5AE63 /* IJSVGLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756523905F6B00F5AE63 /* IJSVGLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75D723905F7300F5AE63 /* IJSVGGradientLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756623905F6B00F5AE63 /* IJSVGGradientLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75D823905F7300F5AE63 /* IJSVGStyleSheetRule.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB756723905F6B00F5AE63 /* IJSVGStyleSheetRule.m */; };
@@ -57,7 +59,6 @@
59EB760123905F7300F5AE63 /* IJSVGLayerTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759023905F6D00F5AE63 /* IJSVGLayerTree.m */; };
59EB760223905F7300F5AE63 /* IJSVGCommandVerticalLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759123905F6D00F5AE63 /* IJSVGCommandVerticalLine.m */; };
59EB760323905F7300F5AE63 /* IJSVGNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759223905F6D00F5AE63 /* IJSVGNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB760423905F7300F5AE63 /* IJSVGCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759323905F6D00F5AE63 /* IJSVGCache.m */; };
59EB760523905F7300F5AE63 /* IJSVGUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759423905F6D00F5AE63 /* IJSVGUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB760623905F7300F5AE63 /* IJSVGCommandHorizontalLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759523905F6D00F5AE63 /* IJSVGCommandHorizontalLine.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB760723905F7300F5AE63 /* IJSVGNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759623905F6D00F5AE63 /* IJSVGNode.m */; };
@@ -100,7 +101,6 @@
59EB762C23905F7300F5AE63 /* IJSVGPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75BB23905F7000F5AE63 /* IJSVGPattern.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB762D23905F7300F5AE63 /* IJSVGLayerTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75BC23905F7000F5AE63 /* IJSVGLayerTree.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB762E23905F7300F5AE63 /* IJSVGExporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75BD23905F7000F5AE63 /* IJSVGExporter.m */; };
59EB762F23905F7300F5AE63 /* IJSVGCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75BE23905F7000F5AE63 /* IJSVGCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB763023905F7300F5AE63 /* IJSVGPatternLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75BF23905F7000F5AE63 /* IJSVGPatternLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB763123905F7300F5AE63 /* IJSVGText.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75C023905F7100F5AE63 /* IJSVGText.m */; };
59EB763223905F7300F5AE63 /* IJSVGView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75C123905F7100F5AE63 /* IJSVGView.m */; };
@@ -133,119 +133,119 @@
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; };
599EB4D2238FF535004CB6BC /* libobjc.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libobjc.tbd; path = usr/lib/libobjc.tbd; sourceTree = SDKROOT; };
59EB756523905F6B00F5AE63 /* IJSVGLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGLayer.h; path = ../../../../source/IJSVGLayer.h; sourceTree = "<group>"; };
59EB756623905F6B00F5AE63 /* IJSVGGradientLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGGradientLayer.h; path = ../../../../source/IJSVGGradientLayer.h; sourceTree = "<group>"; };
59EB756723905F6B00F5AE63 /* IJSVGStyleSheetRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGStyleSheetRule.m; path = ../../../../source/IJSVGStyleSheetRule.m; sourceTree = "<group>"; };
59EB756823905F6B00F5AE63 /* IJSVGCommandLineTo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCommandLineTo.h; path = ../../../../source/IJSVGCommandLineTo.h; sourceTree = "<group>"; };
59EB756923905F6B00F5AE63 /* IJSVGDef.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGDef.m; path = ../../../../source/IJSVGDef.m; sourceTree = "<group>"; };
59EB756A23905F6B00F5AE63 /* IJSVG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVG.h; path = ../../../../source/IJSVG.h; sourceTree = "<group>"; };
59EB756B23905F6B00F5AE63 /* IJSVGText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGText.h; path = ../../../../source/IJSVGText.h; sourceTree = "<group>"; };
59EB756C23905F6B00F5AE63 /* IJSVGCommandQuadraticCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommandQuadraticCurve.m; path = ../../../../source/IJSVGCommandQuadraticCurve.m; sourceTree = "<group>"; };
59EB756D23905F6C00F5AE63 /* IJSVGCommandVerticalLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCommandVerticalLine.h; path = ../../../../source/IJSVGCommandVerticalLine.h; sourceTree = "<group>"; };
59EB756E23905F6C00F5AE63 /* IJSVGWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGWriter.h; path = ../../../../source/IJSVGWriter.h; sourceTree = "<group>"; };
59EB756F23905F6C00F5AE63 /* IJSVGStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGStyleSheet.h; path = ../../../../source/IJSVGStyleSheet.h; sourceTree = "<group>"; };
59EB757023905F6C00F5AE63 /* IJSVGCommandSmoothCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCommandSmoothCurve.h; path = ../../../../source/IJSVGCommandSmoothCurve.h; sourceTree = "<group>"; };
59EB757123905F6C00F5AE63 /* IJSVGColorList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGColorList.m; path = ../../../../source/IJSVGColorList.m; sourceTree = "<group>"; };
59EB757223905F6C00F5AE63 /* IJSVGRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGRadialGradient.h; path = ../../../../source/IJSVGRadialGradient.h; sourceTree = "<group>"; };
59EB757323905F6C00F5AE63 /* IJSVGGradientUnitLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGGradientUnitLength.h; path = ../../../../source/IJSVGGradientUnitLength.h; sourceTree = "<group>"; };
59EB757423905F6C00F5AE63 /* IJSVGStrokeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGStrokeLayer.m; path = ../../../../source/IJSVGStrokeLayer.m; sourceTree = "<group>"; };
59EB757523905F6C00F5AE63 /* IJSVGStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGStyle.m; path = ../../../../source/IJSVGStyle.m; sourceTree = "<group>"; };
59EB757623905F6C00F5AE63 /* IJSVGImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGImage.m; path = ../../../../source/IJSVGImage.m; sourceTree = "<group>"; };
59EB757723905F6C00F5AE63 /* IJSVGUnitLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGUnitLength.h; path = ../../../../source/IJSVGUnitLength.h; sourceTree = "<group>"; };
59EB757823905F6C00F5AE63 /* IJSVGStringAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGStringAdditions.m; path = ../../../../source/IJSVGStringAdditions.m; sourceTree = "<group>"; };
59EB757923905F6C00F5AE63 /* IJSVGTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGTransaction.h; path = ../../../../source/IJSVGTransaction.h; sourceTree = "<group>"; };
59EB757A23905F6C00F5AE63 /* IJSVGShapeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGShapeLayer.m; path = ../../../../source/IJSVGShapeLayer.m; sourceTree = "<group>"; };
59EB757B23905F6C00F5AE63 /* IJSVGLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGLayer.m; path = ../../../../source/IJSVGLayer.m; sourceTree = "<group>"; };
59EB757C23905F6C00F5AE63 /* IJSVGFontConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGFontConverter.m; path = ../../../../source/IJSVGFontConverter.m; sourceTree = "<group>"; };
59EB757D23905F6C00F5AE63 /* IJSVGImageRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGImageRep.m; path = ../../../../source/IJSVGImageRep.m; sourceTree = "<group>"; };
59EB757E23905F6C00F5AE63 /* IJSVGCommandQuadraticCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCommandQuadraticCurve.h; path = ../../../../source/IJSVGCommandQuadraticCurve.h; sourceTree = "<group>"; };
59EB757F23905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGStyleSheetSelectorRaw.h; path = ../../../../source/IJSVGStyleSheetSelectorRaw.h; sourceTree = "<group>"; };
59EB758023905F6C00F5AE63 /* IJSVGUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGUtils.m; path = ../../../../source/IJSVGUtils.m; sourceTree = "<group>"; };
59EB758123905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGStyleSheetSelectorRaw.m; path = ../../../../source/IJSVGStyleSheetSelectorRaw.m; sourceTree = "<group>"; };
59EB758223905F6C00F5AE63 /* IJSVGGroupLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGGroupLayer.m; path = ../../../../source/IJSVGGroupLayer.m; sourceTree = "<group>"; };
59EB758323905F6C00F5AE63 /* IJSVGColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGColor.h; path = ../../../../source/IJSVGColor.h; sourceTree = "<group>"; };
59EB758423905F6C00F5AE63 /* IJSVGError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGError.h; path = ../../../../source/IJSVGError.h; sourceTree = "<group>"; };
59EB758523905F6C00F5AE63 /* IJSVGColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGColor.m; path = ../../../../source/IJSVGColor.m; sourceTree = "<group>"; };
59EB758623905F6C00F5AE63 /* IJSVGDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGDef.h; path = ../../../../source/IJSVGDef.h; sourceTree = "<group>"; };
59EB758723905F6C00F5AE63 /* IJSVGCommandHorizontalLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommandHorizontalLine.m; path = ../../../../source/IJSVGCommandHorizontalLine.m; sourceTree = "<group>"; };
59EB758823905F6D00F5AE63 /* IJSVGFontConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGFontConverter.h; path = ../../../../source/IJSVGFontConverter.h; sourceTree = "<group>"; };
59EB758923905F6D00F5AE63 /* IJSVGWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGWriter.m; path = ../../../../source/IJSVGWriter.m; sourceTree = "<group>"; };
59EB758A23905F6D00F5AE63 /* IJSVGPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGPath.m; path = ../../../../source/IJSVGPath.m; sourceTree = "<group>"; };
59EB758B23905F6D00F5AE63 /* IJSVGGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGGroup.h; path = ../../../../source/IJSVGGroup.h; sourceTree = "<group>"; };
59EB758C23905F6D00F5AE63 /* IJSVGPatternLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGPatternLayer.m; path = ../../../../source/IJSVGPatternLayer.m; sourceTree = "<group>"; };
59EB758D23905F6D00F5AE63 /* IJSVGRenderingStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGRenderingStyle.m; path = ../../../../source/IJSVGRenderingStyle.m; sourceTree = "<group>"; };
59EB758E23905F6D00F5AE63 /* IJSVGBezierPathAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGBezierPathAdditions.m; path = ../../../../source/IJSVGBezierPathAdditions.m; sourceTree = "<group>"; };
59EB758F23905F6D00F5AE63 /* IJSVGGradientLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGGradientLayer.m; path = ../../../../source/IJSVGGradientLayer.m; sourceTree = "<group>"; };
59EB759023905F6D00F5AE63 /* IJSVGLayerTree.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGLayerTree.m; path = ../../../../source/IJSVGLayerTree.m; sourceTree = "<group>"; };
59EB759123905F6D00F5AE63 /* IJSVGCommandVerticalLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommandVerticalLine.m; path = ../../../../source/IJSVGCommandVerticalLine.m; sourceTree = "<group>"; };
59EB759223905F6D00F5AE63 /* IJSVGNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGNode.h; path = ../../../../source/IJSVGNode.h; sourceTree = "<group>"; };
59EB759323905F6D00F5AE63 /* IJSVGCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCache.m; path = ../../../../source/IJSVGCache.m; sourceTree = "<group>"; };
59EB759423905F6D00F5AE63 /* IJSVGUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGUtils.h; path = ../../../../source/IJSVGUtils.h; sourceTree = "<group>"; };
59EB759523905F6D00F5AE63 /* IJSVGCommandHorizontalLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCommandHorizontalLine.h; path = ../../../../source/IJSVGCommandHorizontalLine.h; sourceTree = "<group>"; };
59EB759623905F6D00F5AE63 /* IJSVGNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGNode.m; path = ../../../../source/IJSVGNode.m; sourceTree = "<group>"; };
59EB759723905F6D00F5AE63 /* IJSVGShapeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGShapeLayer.h; path = ../../../../source/IJSVGShapeLayer.h; sourceTree = "<group>"; };
59EB759823905F6E00F5AE63 /* IJSVGCommandCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommandCurve.m; path = ../../../../source/IJSVGCommandCurve.m; sourceTree = "<group>"; };
59EB759923905F6E00F5AE63 /* IJSVGCommandMove.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommandMove.m; path = ../../../../source/IJSVGCommandMove.m; sourceTree = "<group>"; };
59EB759A23905F6E00F5AE63 /* IJSVGStyleSheetSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGStyleSheetSelector.h; path = ../../../../source/IJSVGStyleSheetSelector.h; sourceTree = "<group>"; };
59EB759B23905F6E00F5AE63 /* IJSVGStyleSheetRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGStyleSheetRule.h; path = ../../../../source/IJSVGStyleSheetRule.h; sourceTree = "<group>"; };
59EB759C23905F6E00F5AE63 /* IJSVGCommandCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCommandCurve.h; path = ../../../../source/IJSVGCommandCurve.h; sourceTree = "<group>"; };
59EB759D23905F6E00F5AE63 /* IJSVGPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGPath.h; path = ../../../../source/IJSVGPath.h; sourceTree = "<group>"; };
59EB759E23905F6E00F5AE63 /* IJSVGCommandEllipticalArc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCommandEllipticalArc.h; path = ../../../../source/IJSVGCommandEllipticalArc.h; sourceTree = "<group>"; };
59EB759F23905F6E00F5AE63 /* IJSVGLinearGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGLinearGradient.h; path = ../../../../source/IJSVGLinearGradient.h; sourceTree = "<group>"; };
59EB75A023905F6E00F5AE63 /* IJSVGCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommand.m; path = ../../../../source/IJSVGCommand.m; sourceTree = "<group>"; };
59EB75A123905F6E00F5AE63 /* IJSVGRenderingStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGRenderingStyle.h; path = ../../../../source/IJSVGRenderingStyle.h; sourceTree = "<group>"; };
59EB75A223905F6E00F5AE63 /* IJSVG.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVG.m; path = ../../../../source/IJSVG.m; sourceTree = "<group>"; };
59EB75A323905F6E00F5AE63 /* IJSVGImageRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGImageRep.h; path = ../../../../source/IJSVGImageRep.h; sourceTree = "<group>"; };
59EB75A423905F6E00F5AE63 /* IJSVGStrokeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGStrokeLayer.h; path = ../../../../source/IJSVGStrokeLayer.h; sourceTree = "<group>"; };
59EB75A523905F6E00F5AE63 /* IJSVGParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGParser.m; path = ../../../../source/IJSVGParser.m; sourceTree = "<group>"; };
59EB75A623905F6F00F5AE63 /* IJSVGRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGRadialGradient.m; path = ../../../../source/IJSVGRadialGradient.m; sourceTree = "<group>"; };
59EB75A723905F6F00F5AE63 /* IJSVGParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGParser.h; path = ../../../../source/IJSVGParser.h; sourceTree = "<group>"; };
59EB75A823905F6F00F5AE63 /* IJSVGCommandSmoothCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommandSmoothCurve.m; path = ../../../../source/IJSVGCommandSmoothCurve.m; sourceTree = "<group>"; };
59EB75A923905F6F00F5AE63 /* IJSVGColorList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGColorList.h; path = ../../../../source/IJSVGColorList.h; sourceTree = "<group>"; };
59EB75AA23905F6F00F5AE63 /* IJSVGPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGPattern.m; path = ../../../../source/IJSVGPattern.m; sourceTree = "<group>"; };
59EB75AB23905F6F00F5AE63 /* IJSVGGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGGradient.h; path = ../../../../source/IJSVGGradient.h; sourceTree = "<group>"; };
59EB75AC23905F6F00F5AE63 /* IJSVGStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGStyle.h; path = ../../../../source/IJSVGStyle.h; sourceTree = "<group>"; };
59EB75AD23905F6F00F5AE63 /* IJSVGGroupLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGGroupLayer.h; path = ../../../../source/IJSVGGroupLayer.h; sourceTree = "<group>"; };
59EB75AE23905F6F00F5AE63 /* IJSVGCommandLineTo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommandLineTo.m; path = ../../../../source/IJSVGCommandLineTo.m; sourceTree = "<group>"; };
59EB75AF23905F6F00F5AE63 /* IJSVGCommandMove.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCommandMove.h; path = ../../../../source/IJSVGCommandMove.h; sourceTree = "<group>"; };
59EB75B023905F6F00F5AE63 /* IJSVGTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGTransform.h; path = ../../../../source/IJSVGTransform.h; sourceTree = "<group>"; };
59EB75B123905F6F00F5AE63 /* IJSVGMath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGMath.m; path = ../../../../source/IJSVGMath.m; sourceTree = "<group>"; };
59EB75B223905F6F00F5AE63 /* IJSVGExporterPathInstruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGExporterPathInstruction.h; path = ../../../../source/IJSVGExporterPathInstruction.h; sourceTree = "<group>"; };
59EB75B323905F6F00F5AE63 /* IJSVGTransaction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGTransaction.m; path = ../../../../source/IJSVGTransaction.m; sourceTree = "<group>"; };
59EB75B423905F6F00F5AE63 /* IJSVGTransform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGTransform.m; path = ../../../../source/IJSVGTransform.m; sourceTree = "<group>"; };
59EB75B523905F7000F5AE63 /* IJSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGImage.h; path = ../../../../source/IJSVGImage.h; sourceTree = "<group>"; };
59EB75B623905F7000F5AE63 /* IJSVGMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGMath.h; path = ../../../../source/IJSVGMath.h; sourceTree = "<group>"; };
59EB75B723905F7000F5AE63 /* IJSVGCommandClose.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCommandClose.h; path = ../../../../source/IJSVGCommandClose.h; sourceTree = "<group>"; };
59EB75B823905F7000F5AE63 /* IJSVGStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGStringAdditions.h; path = ../../../../source/IJSVGStringAdditions.h; sourceTree = "<group>"; };
59EB75B923905F7000F5AE63 /* IJSVGGradientUnitLength.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGGradientUnitLength.m; path = ../../../../source/IJSVGGradientUnitLength.m; sourceTree = "<group>"; };
59EB75BA23905F7000F5AE63 /* IJSVGUnitLength.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGUnitLength.m; path = ../../../../source/IJSVGUnitLength.m; sourceTree = "<group>"; };
59EB75BB23905F7000F5AE63 /* IJSVGPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGPattern.h; path = ../../../../source/IJSVGPattern.h; sourceTree = "<group>"; };
59EB75BC23905F7000F5AE63 /* IJSVGLayerTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGLayerTree.h; path = ../../../../source/IJSVGLayerTree.h; sourceTree = "<group>"; };
59EB75BD23905F7000F5AE63 /* IJSVGExporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGExporter.m; path = ../../../../source/IJSVGExporter.m; sourceTree = "<group>"; };
59EB75BE23905F7000F5AE63 /* IJSVGCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCache.h; path = ../../../../source/IJSVGCache.h; sourceTree = "<group>"; };
59EB75BF23905F7000F5AE63 /* IJSVGPatternLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGPatternLayer.h; path = ../../../../source/IJSVGPatternLayer.h; sourceTree = "<group>"; };
59EB75C023905F7100F5AE63 /* IJSVGText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGText.m; path = ../../../../source/IJSVGText.m; sourceTree = "<group>"; };
59EB75C123905F7100F5AE63 /* IJSVGView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGView.m; path = ../../../../source/IJSVGView.m; sourceTree = "<group>"; };
59EB75C223905F7100F5AE63 /* IJSVGLinearGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGLinearGradient.m; path = ../../../../source/IJSVGLinearGradient.m; sourceTree = "<group>"; };
59EB75C323905F7100F5AE63 /* IJSVGBezierPathAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGBezierPathAdditions.h; path = ../../../../source/IJSVGBezierPathAdditions.h; sourceTree = "<group>"; };
59EB75C423905F7100F5AE63 /* IJSVGStyleSheetSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGStyleSheetSelector.m; path = ../../../../source/IJSVGStyleSheetSelector.m; sourceTree = "<group>"; };
59EB75C523905F7100F5AE63 /* IJSVGImageLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGImageLayer.m; path = ../../../../source/IJSVGImageLayer.m; sourceTree = "<group>"; };
59EB75C623905F7100F5AE63 /* IJSVGCommandClose.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommandClose.m; path = ../../../../source/IJSVGCommandClose.m; sourceTree = "<group>"; };
59EB75C723905F7100F5AE63 /* IJSVGCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCommand.h; path = ../../../../source/IJSVGCommand.h; sourceTree = "<group>"; };
59EB75C823905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommandSmoothQuadraticCurve.m; path = ../../../../source/IJSVGCommandSmoothQuadraticCurve.m; sourceTree = "<group>"; };
59EB75C923905F7200F5AE63 /* IJSVGForeignObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGForeignObject.m; path = ../../../../source/IJSVGForeignObject.m; sourceTree = "<group>"; };
59EB75CA23905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCommandSmoothQuadraticCurve.h; path = ../../../../source/IJSVGCommandSmoothQuadraticCurve.h; sourceTree = "<group>"; };
59EB75CB23905F7200F5AE63 /* IJSVGCommandEllipticalArc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommandEllipticalArc.m; path = ../../../../source/IJSVGCommandEllipticalArc.m; sourceTree = "<group>"; };
59EB75CC23905F7200F5AE63 /* IJSVGGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGGroup.m; path = ../../../../source/IJSVGGroup.m; sourceTree = "<group>"; };
59EB75CD23905F7200F5AE63 /* IJSVGView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGView.h; path = ../../../../source/IJSVGView.h; sourceTree = "<group>"; };
59EB75CE23905F7200F5AE63 /* IJSVGForeignObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGForeignObject.h; path = ../../../../source/IJSVGForeignObject.h; sourceTree = "<group>"; };
59EB75CF23905F7200F5AE63 /* IJSVGExporterPathInstruction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGExporterPathInstruction.m; path = ../../../../source/IJSVGExporterPathInstruction.m; sourceTree = "<group>"; };
59EB75D023905F7200F5AE63 /* IJSVGImageLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGImageLayer.h; path = ../../../../source/IJSVGImageLayer.h; sourceTree = "<group>"; };
59EB75D123905F7300F5AE63 /* IJSVGStyleSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGStyleSheet.m; path = ../../../../source/IJSVGStyleSheet.m; sourceTree = "<group>"; };
59EB75D223905F7300F5AE63 /* IJSVGGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGGradient.m; path = ../../../../source/IJSVGGradient.m; sourceTree = "<group>"; };
59EB75D323905F7300F5AE63 /* IJSVGRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGRendering.h; path = ../../../../source/IJSVGRendering.h; sourceTree = "<group>"; };
59EB75D423905F7300F5AE63 /* IJSVGExporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGExporter.h; path = ../../../../source/IJSVGExporter.h; sourceTree = "<group>"; };
59EB75D523905F7300F5AE63 /* IJSVGRendering.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGRendering.m; path = ../../../../source/IJSVGRendering.m; sourceTree = "<group>"; };
59E7CFAD23B148600077D599 /* IJSVGCommandParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IJSVGCommandParser.h; path = IJSVG/Source/Parsing/IJSVGCommandParser.h; sourceTree = SOURCE_ROOT; };
59E7CFAE23B148600077D599 /* IJSVGCommandParser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = IJSVGCommandParser.m; path = IJSVG/Source/Parsing/IJSVGCommandParser.m; sourceTree = SOURCE_ROOT; };
59EB756523905F6B00F5AE63 /* IJSVGLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGLayer.h; sourceTree = "<group>"; };
59EB756623905F6B00F5AE63 /* IJSVGGradientLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGradientLayer.h; sourceTree = "<group>"; };
59EB756723905F6B00F5AE63 /* IJSVGStyleSheetRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheetRule.m; sourceTree = "<group>"; };
59EB756823905F6B00F5AE63 /* IJSVGCommandLineTo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandLineTo.h; sourceTree = "<group>"; };
59EB756923905F6B00F5AE63 /* IJSVGDef.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGDef.m; sourceTree = "<group>"; };
59EB756A23905F6B00F5AE63 /* IJSVG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVG.h; sourceTree = "<group>"; };
59EB756B23905F6B00F5AE63 /* IJSVGText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGText.h; sourceTree = "<group>"; };
59EB756C23905F6B00F5AE63 /* IJSVGCommandQuadraticCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandQuadraticCurve.m; sourceTree = "<group>"; };
59EB756D23905F6C00F5AE63 /* IJSVGCommandVerticalLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandVerticalLine.h; sourceTree = "<group>"; };
59EB756E23905F6C00F5AE63 /* IJSVGWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGWriter.h; sourceTree = "<group>"; };
59EB756F23905F6C00F5AE63 /* IJSVGStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheet.h; sourceTree = "<group>"; };
59EB757023905F6C00F5AE63 /* IJSVGCommandSmoothCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandSmoothCurve.h; sourceTree = "<group>"; };
59EB757123905F6C00F5AE63 /* IJSVGColorList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGColorList.m; sourceTree = "<group>"; };
59EB757223905F6C00F5AE63 /* IJSVGRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGRadialGradient.h; sourceTree = "<group>"; };
59EB757323905F6C00F5AE63 /* IJSVGGradientUnitLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGradientUnitLength.h; sourceTree = "<group>"; };
59EB757423905F6C00F5AE63 /* IJSVGStrokeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStrokeLayer.m; sourceTree = "<group>"; };
59EB757523905F6C00F5AE63 /* IJSVGStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyle.m; sourceTree = "<group>"; };
59EB757623905F6C00F5AE63 /* IJSVGImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGImage.m; sourceTree = "<group>"; };
59EB757723905F6C00F5AE63 /* IJSVGUnitLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGUnitLength.h; sourceTree = "<group>"; };
59EB757823905F6C00F5AE63 /* IJSVGStringAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStringAdditions.m; sourceTree = "<group>"; };
59EB757923905F6C00F5AE63 /* IJSVGTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGTransaction.h; sourceTree = "<group>"; };
59EB757A23905F6C00F5AE63 /* IJSVGShapeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGShapeLayer.m; sourceTree = "<group>"; };
59EB757B23905F6C00F5AE63 /* IJSVGLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGLayer.m; sourceTree = "<group>"; };
59EB757C23905F6C00F5AE63 /* IJSVGFontConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGFontConverter.m; sourceTree = "<group>"; };
59EB757D23905F6C00F5AE63 /* IJSVGImageRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGImageRep.m; sourceTree = "<group>"; };
59EB757E23905F6C00F5AE63 /* IJSVGCommandQuadraticCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandQuadraticCurve.h; sourceTree = "<group>"; };
59EB757F23905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheetSelectorRaw.h; sourceTree = "<group>"; };
59EB758023905F6C00F5AE63 /* IJSVGUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGUtils.m; sourceTree = "<group>"; };
59EB758123905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheetSelectorRaw.m; sourceTree = "<group>"; };
59EB758223905F6C00F5AE63 /* IJSVGGroupLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGroupLayer.m; sourceTree = "<group>"; };
59EB758323905F6C00F5AE63 /* IJSVGColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGColor.h; sourceTree = "<group>"; };
59EB758423905F6C00F5AE63 /* IJSVGError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGError.h; sourceTree = "<group>"; };
59EB758523905F6C00F5AE63 /* IJSVGColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGColor.m; sourceTree = "<group>"; };
59EB758623905F6C00F5AE63 /* IJSVGDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGDef.h; sourceTree = "<group>"; };
59EB758723905F6C00F5AE63 /* IJSVGCommandHorizontalLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandHorizontalLine.m; sourceTree = "<group>"; };
59EB758823905F6D00F5AE63 /* IJSVGFontConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGFontConverter.h; sourceTree = "<group>"; };
59EB758923905F6D00F5AE63 /* IJSVGWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGWriter.m; sourceTree = "<group>"; };
59EB758A23905F6D00F5AE63 /* IJSVGPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGPath.m; sourceTree = "<group>"; };
59EB758B23905F6D00F5AE63 /* IJSVGGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGroup.h; sourceTree = "<group>"; };
59EB758C23905F6D00F5AE63 /* IJSVGPatternLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGPatternLayer.m; sourceTree = "<group>"; };
59EB758D23905F6D00F5AE63 /* IJSVGRenderingStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGRenderingStyle.m; sourceTree = "<group>"; };
59EB758E23905F6D00F5AE63 /* IJSVGBezierPathAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGBezierPathAdditions.m; sourceTree = "<group>"; };
59EB758F23905F6D00F5AE63 /* IJSVGGradientLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGradientLayer.m; sourceTree = "<group>"; };
59EB759023905F6D00F5AE63 /* IJSVGLayerTree.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGLayerTree.m; sourceTree = "<group>"; };
59EB759123905F6D00F5AE63 /* IJSVGCommandVerticalLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandVerticalLine.m; sourceTree = "<group>"; };
59EB759223905F6D00F5AE63 /* IJSVGNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGNode.h; sourceTree = "<group>"; };
59EB759423905F6D00F5AE63 /* IJSVGUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGUtils.h; sourceTree = "<group>"; };
59EB759523905F6D00F5AE63 /* IJSVGCommandHorizontalLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandHorizontalLine.h; sourceTree = "<group>"; };
59EB759623905F6D00F5AE63 /* IJSVGNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGNode.m; sourceTree = "<group>"; };
59EB759723905F6D00F5AE63 /* IJSVGShapeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGShapeLayer.h; sourceTree = "<group>"; };
59EB759823905F6E00F5AE63 /* IJSVGCommandCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandCurve.m; sourceTree = "<group>"; };
59EB759923905F6E00F5AE63 /* IJSVGCommandMove.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandMove.m; sourceTree = "<group>"; };
59EB759A23905F6E00F5AE63 /* IJSVGStyleSheetSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheetSelector.h; sourceTree = "<group>"; };
59EB759B23905F6E00F5AE63 /* IJSVGStyleSheetRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheetRule.h; sourceTree = "<group>"; };
59EB759C23905F6E00F5AE63 /* IJSVGCommandCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandCurve.h; sourceTree = "<group>"; };
59EB759D23905F6E00F5AE63 /* IJSVGPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGPath.h; sourceTree = "<group>"; };
59EB759E23905F6E00F5AE63 /* IJSVGCommandEllipticalArc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandEllipticalArc.h; sourceTree = "<group>"; };
59EB759F23905F6E00F5AE63 /* IJSVGLinearGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGLinearGradient.h; sourceTree = "<group>"; };
59EB75A023905F6E00F5AE63 /* IJSVGCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommand.m; sourceTree = "<group>"; };
59EB75A123905F6E00F5AE63 /* IJSVGRenderingStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGRenderingStyle.h; sourceTree = "<group>"; };
59EB75A223905F6E00F5AE63 /* IJSVG.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVG.m; sourceTree = "<group>"; };
59EB75A323905F6E00F5AE63 /* IJSVGImageRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGImageRep.h; sourceTree = "<group>"; };
59EB75A423905F6E00F5AE63 /* IJSVGStrokeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStrokeLayer.h; sourceTree = "<group>"; };
59EB75A523905F6E00F5AE63 /* IJSVGParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGParser.m; sourceTree = "<group>"; };
59EB75A623905F6F00F5AE63 /* IJSVGRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGRadialGradient.m; sourceTree = "<group>"; };
59EB75A723905F6F00F5AE63 /* IJSVGParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGParser.h; sourceTree = "<group>"; };
59EB75A823905F6F00F5AE63 /* IJSVGCommandSmoothCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandSmoothCurve.m; sourceTree = "<group>"; };
59EB75A923905F6F00F5AE63 /* IJSVGColorList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGColorList.h; sourceTree = "<group>"; };
59EB75AA23905F6F00F5AE63 /* IJSVGPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGPattern.m; sourceTree = "<group>"; };
59EB75AB23905F6F00F5AE63 /* IJSVGGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGradient.h; sourceTree = "<group>"; };
59EB75AC23905F6F00F5AE63 /* IJSVGStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyle.h; sourceTree = "<group>"; };
59EB75AD23905F6F00F5AE63 /* IJSVGGroupLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGroupLayer.h; sourceTree = "<group>"; };
59EB75AE23905F6F00F5AE63 /* IJSVGCommandLineTo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandLineTo.m; sourceTree = "<group>"; };
59EB75AF23905F6F00F5AE63 /* IJSVGCommandMove.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandMove.h; sourceTree = "<group>"; };
59EB75B023905F6F00F5AE63 /* IJSVGTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGTransform.h; sourceTree = "<group>"; };
59EB75B123905F6F00F5AE63 /* IJSVGMath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGMath.m; sourceTree = "<group>"; };
59EB75B223905F6F00F5AE63 /* IJSVGExporterPathInstruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGExporterPathInstruction.h; sourceTree = "<group>"; };
59EB75B323905F6F00F5AE63 /* IJSVGTransaction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGTransaction.m; sourceTree = "<group>"; };
59EB75B423905F6F00F5AE63 /* IJSVGTransform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGTransform.m; sourceTree = "<group>"; };
59EB75B523905F7000F5AE63 /* IJSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGImage.h; sourceTree = "<group>"; };
59EB75B623905F7000F5AE63 /* IJSVGMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGMath.h; sourceTree = "<group>"; };
59EB75B723905F7000F5AE63 /* IJSVGCommandClose.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandClose.h; sourceTree = "<group>"; };
59EB75B823905F7000F5AE63 /* IJSVGStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStringAdditions.h; sourceTree = "<group>"; };
59EB75B923905F7000F5AE63 /* IJSVGGradientUnitLength.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGradientUnitLength.m; sourceTree = "<group>"; };
59EB75BA23905F7000F5AE63 /* IJSVGUnitLength.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGUnitLength.m; sourceTree = "<group>"; };
59EB75BB23905F7000F5AE63 /* IJSVGPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGPattern.h; sourceTree = "<group>"; };
59EB75BC23905F7000F5AE63 /* IJSVGLayerTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGLayerTree.h; sourceTree = "<group>"; };
59EB75BD23905F7000F5AE63 /* IJSVGExporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGExporter.m; sourceTree = "<group>"; };
59EB75BF23905F7000F5AE63 /* IJSVGPatternLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGPatternLayer.h; sourceTree = "<group>"; };
59EB75C023905F7100F5AE63 /* IJSVGText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGText.m; sourceTree = "<group>"; };
59EB75C123905F7100F5AE63 /* IJSVGView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGView.m; sourceTree = "<group>"; };
59EB75C223905F7100F5AE63 /* IJSVGLinearGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGLinearGradient.m; sourceTree = "<group>"; };
59EB75C323905F7100F5AE63 /* IJSVGBezierPathAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGBezierPathAdditions.h; sourceTree = "<group>"; };
59EB75C423905F7100F5AE63 /* IJSVGStyleSheetSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheetSelector.m; sourceTree = "<group>"; };
59EB75C523905F7100F5AE63 /* IJSVGImageLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGImageLayer.m; sourceTree = "<group>"; };
59EB75C623905F7100F5AE63 /* IJSVGCommandClose.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandClose.m; sourceTree = "<group>"; };
59EB75C723905F7100F5AE63 /* IJSVGCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommand.h; sourceTree = "<group>"; };
59EB75C823905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandSmoothQuadraticCurve.m; sourceTree = "<group>"; };
59EB75C923905F7200F5AE63 /* IJSVGForeignObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGForeignObject.m; sourceTree = "<group>"; };
59EB75CA23905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandSmoothQuadraticCurve.h; sourceTree = "<group>"; };
59EB75CB23905F7200F5AE63 /* IJSVGCommandEllipticalArc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandEllipticalArc.m; sourceTree = "<group>"; };
59EB75CC23905F7200F5AE63 /* IJSVGGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGroup.m; sourceTree = "<group>"; };
59EB75CD23905F7200F5AE63 /* IJSVGView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGView.h; sourceTree = "<group>"; };
59EB75CE23905F7200F5AE63 /* IJSVGForeignObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGForeignObject.h; sourceTree = "<group>"; };
59EB75CF23905F7200F5AE63 /* IJSVGExporterPathInstruction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGExporterPathInstruction.m; sourceTree = "<group>"; };
59EB75D023905F7200F5AE63 /* IJSVGImageLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGImageLayer.h; sourceTree = "<group>"; };
59EB75D123905F7300F5AE63 /* IJSVGStyleSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheet.m; sourceTree = "<group>"; };
59EB75D223905F7300F5AE63 /* IJSVGGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGradient.m; sourceTree = "<group>"; };
59EB75D323905F7300F5AE63 /* IJSVGRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGRendering.h; sourceTree = "<group>"; };
59EB75D423905F7300F5AE63 /* IJSVGExporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGExporter.h; sourceTree = "<group>"; };
59EB75D523905F7300F5AE63 /* IJSVGRendering.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGRendering.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -263,6 +263,178 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
592ABBE223979F9B00F44380 /* Commands */ = {
isa = PBXGroup;
children = (
59EB75C723905F7100F5AE63 /* IJSVGCommand.h */,
59EB75A023905F6E00F5AE63 /* IJSVGCommand.m */,
59EB75B723905F7000F5AE63 /* IJSVGCommandClose.h */,
59EB75C623905F7100F5AE63 /* IJSVGCommandClose.m */,
59EB759C23905F6E00F5AE63 /* IJSVGCommandCurve.h */,
59EB759823905F6E00F5AE63 /* IJSVGCommandCurve.m */,
59EB759E23905F6E00F5AE63 /* IJSVGCommandEllipticalArc.h */,
59EB75CB23905F7200F5AE63 /* IJSVGCommandEllipticalArc.m */,
59EB759523905F6D00F5AE63 /* IJSVGCommandHorizontalLine.h */,
59EB758723905F6C00F5AE63 /* IJSVGCommandHorizontalLine.m */,
59EB756823905F6B00F5AE63 /* IJSVGCommandLineTo.h */,
59EB75AE23905F6F00F5AE63 /* IJSVGCommandLineTo.m */,
59EB75AF23905F6F00F5AE63 /* IJSVGCommandMove.h */,
59EB759923905F6E00F5AE63 /* IJSVGCommandMove.m */,
59EB757E23905F6C00F5AE63 /* IJSVGCommandQuadraticCurve.h */,
59EB756C23905F6B00F5AE63 /* IJSVGCommandQuadraticCurve.m */,
59EB757023905F6C00F5AE63 /* IJSVGCommandSmoothCurve.h */,
59EB75A823905F6F00F5AE63 /* IJSVGCommandSmoothCurve.m */,
59EB75CA23905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.h */,
59EB75C823905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.m */,
59EB756D23905F6C00F5AE63 /* IJSVGCommandVerticalLine.h */,
59EB759123905F6D00F5AE63 /* IJSVGCommandVerticalLine.m */,
);
path = Commands;
sourceTree = "<group>";
};
592ABBE323979FBB00F44380 /* Stylesheets */ = {
isa = PBXGroup;
children = (
59EB75AC23905F6F00F5AE63 /* IJSVGStyle.h */,
59EB757523905F6C00F5AE63 /* IJSVGStyle.m */,
59EB756F23905F6C00F5AE63 /* IJSVGStyleSheet.h */,
59EB75D123905F7300F5AE63 /* IJSVGStyleSheet.m */,
59EB759B23905F6E00F5AE63 /* IJSVGStyleSheetRule.h */,
59EB756723905F6B00F5AE63 /* IJSVGStyleSheetRule.m */,
59EB759A23905F6E00F5AE63 /* IJSVGStyleSheetSelector.h */,
59EB75C423905F7100F5AE63 /* IJSVGStyleSheetSelector.m */,
59EB757F23905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.h */,
59EB758123905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.m */,
);
path = Stylesheets;
sourceTree = "<group>";
};
592ABBE423979FD200F44380 /* Colors */ = {
isa = PBXGroup;
children = (
59EB758323905F6C00F5AE63 /* IJSVGColor.h */,
59EB758523905F6C00F5AE63 /* IJSVGColor.m */,
59EB75A923905F6F00F5AE63 /* IJSVGColorList.h */,
59EB757123905F6C00F5AE63 /* IJSVGColorList.m */,
);
path = Colors;
sourceTree = "<group>";
};
592ABBE523979FE100F44380 /* Layers */ = {
isa = PBXGroup;
children = (
59EB756623905F6B00F5AE63 /* IJSVGGradientLayer.h */,
59EB758F23905F6D00F5AE63 /* IJSVGGradientLayer.m */,
59EB75AD23905F6F00F5AE63 /* IJSVGGroupLayer.h */,
59EB758223905F6C00F5AE63 /* IJSVGGroupLayer.m */,
59EB75D023905F7200F5AE63 /* IJSVGImageLayer.h */,
59EB75C523905F7100F5AE63 /* IJSVGImageLayer.m */,
59EB756523905F6B00F5AE63 /* IJSVGLayer.h */,
59EB757B23905F6C00F5AE63 /* IJSVGLayer.m */,
59EB75BF23905F7000F5AE63 /* IJSVGPatternLayer.h */,
59EB758C23905F6D00F5AE63 /* IJSVGPatternLayer.m */,
59EB757223905F6C00F5AE63 /* IJSVGRadialGradient.h */,
59EB75A623905F6F00F5AE63 /* IJSVGRadialGradient.m */,
59EB759723905F6D00F5AE63 /* IJSVGShapeLayer.h */,
59EB757A23905F6C00F5AE63 /* IJSVGShapeLayer.m */,
59EB75A423905F6E00F5AE63 /* IJSVGStrokeLayer.h */,
59EB757423905F6C00F5AE63 /* IJSVGStrokeLayer.m */,
);
path = Layers;
sourceTree = "<group>";
};
592ABBE62397A00C00F44380 /* Parsing */ = {
isa = PBXGroup;
children = (
59E7CFAD23B148600077D599 /* IJSVGCommandParser.h */,
59E7CFAE23B148600077D599 /* IJSVGCommandParser.m */,
59EB75A723905F6F00F5AE63 /* IJSVGParser.h */,
59EB75A523905F6E00F5AE63 /* IJSVGParser.m */,
);
path = Parsing;
sourceTree = "<group>";
};
592ABBE72397A02900F44380 /* Nodes */ = {
isa = PBXGroup;
children = (
59EB75CE23905F7200F5AE63 /* IJSVGForeignObject.h */,
59EB75C923905F7200F5AE63 /* IJSVGForeignObject.m */,
59EB758623905F6C00F5AE63 /* IJSVGDef.h */,
59EB756923905F6B00F5AE63 /* IJSVGDef.m */,
59EB759F23905F6E00F5AE63 /* IJSVGLinearGradient.h */,
59EB75C223905F7100F5AE63 /* IJSVGLinearGradient.m */,
59EB75AB23905F6F00F5AE63 /* IJSVGGradient.h */,
59EB75D223905F7300F5AE63 /* IJSVGGradient.m */,
59EB758B23905F6D00F5AE63 /* IJSVGGroup.h */,
59EB75CC23905F7200F5AE63 /* IJSVGGroup.m */,
59EB75B523905F7000F5AE63 /* IJSVGImage.h */,
59EB757623905F6C00F5AE63 /* IJSVGImage.m */,
59EB759223905F6D00F5AE63 /* IJSVGNode.h */,
59EB759623905F6D00F5AE63 /* IJSVGNode.m */,
59EB759D23905F6E00F5AE63 /* IJSVGPath.h */,
59EB758A23905F6D00F5AE63 /* IJSVGPath.m */,
59EB75BB23905F7000F5AE63 /* IJSVGPattern.h */,
59EB75AA23905F6F00F5AE63 /* IJSVGPattern.m */,
59EB756B23905F6B00F5AE63 /* IJSVGText.h */,
59EB75C023905F7100F5AE63 /* IJSVGText.m */,
);
path = Nodes;
sourceTree = "<group>";
};
592ABBE82397A06800F44380 /* Utils */ = {
isa = PBXGroup;
children = (
59EB757323905F6C00F5AE63 /* IJSVGGradientUnitLength.h */,
59EB75B923905F7000F5AE63 /* IJSVGGradientUnitLength.m */,
59EB75B623905F7000F5AE63 /* IJSVGMath.h */,
59EB75B123905F6F00F5AE63 /* IJSVGMath.m */,
59EB757923905F6C00F5AE63 /* IJSVGTransaction.h */,
59EB75B323905F6F00F5AE63 /* IJSVGTransaction.m */,
59EB75B023905F6F00F5AE63 /* IJSVGTransform.h */,
59EB75B423905F6F00F5AE63 /* IJSVGTransform.m */,
59EB757723905F6C00F5AE63 /* IJSVGUnitLength.h */,
59EB75BA23905F7000F5AE63 /* IJSVGUnitLength.m */,
59EB759423905F6D00F5AE63 /* IJSVGUtils.h */,
59EB758023905F6C00F5AE63 /* IJSVGUtils.m */,
);
path = Utils;
sourceTree = "<group>";
};
592ABBE92397A08500F44380 /* Exporter */ = {
isa = PBXGroup;
children = (
59EB75D423905F7300F5AE63 /* IJSVGExporter.h */,
59EB75BD23905F7000F5AE63 /* IJSVGExporter.m */,
59EB75B223905F6F00F5AE63 /* IJSVGExporterPathInstruction.h */,
59EB75CF23905F7200F5AE63 /* IJSVGExporterPathInstruction.m */,
);
path = Exporter;
sourceTree = "<group>";
};
592ABBEA2397A10000F44380 /* Rendering */ = {
isa = PBXGroup;
children = (
59EB75BC23905F7000F5AE63 /* IJSVGLayerTree.h */,
59EB759023905F6D00F5AE63 /* IJSVGLayerTree.m */,
59EB75D323905F7300F5AE63 /* IJSVGRendering.h */,
59EB75D523905F7300F5AE63 /* IJSVGRendering.m */,
59EB75A123905F6E00F5AE63 /* IJSVGRenderingStyle.h */,
59EB758D23905F6D00F5AE63 /* IJSVGRenderingStyle.m */,
);
path = Rendering;
sourceTree = "<group>";
};
592ABBEB2397A11800F44380 /* Additions */ = {
isa = PBXGroup;
children = (
59EB75C323905F7100F5AE63 /* IJSVGBezierPathAdditions.h */,
59EB758E23905F6D00F5AE63 /* IJSVGBezierPathAdditions.m */,
59EB75B823905F7000F5AE63 /* IJSVGStringAdditions.h */,
59EB757823905F6C00F5AE63 /* IJSVGStringAdditions.m */,
);
path = Additions;
sourceTree = "<group>";
};
594CF465238FF38E009B251B = {
isa = PBXGroup;
children = (
@@ -300,123 +472,39 @@
name = Frameworks;
sourceTree = "<group>";
};
59EB756423905F3100F5AE63 /* Source */ = {
59DD1FD123A22CFD00E28C56 /* Core */ = {
isa = PBXGroup;
children = (
59EB756A23905F6B00F5AE63 /* IJSVG.h */,
59EB75A223905F6E00F5AE63 /* IJSVG.m */,
59EB75C323905F7100F5AE63 /* IJSVGBezierPathAdditions.h */,
59EB758E23905F6D00F5AE63 /* IJSVGBezierPathAdditions.m */,
59EB75BE23905F7000F5AE63 /* IJSVGCache.h */,
59EB759323905F6D00F5AE63 /* IJSVGCache.m */,
59EB758323905F6C00F5AE63 /* IJSVGColor.h */,
59EB758523905F6C00F5AE63 /* IJSVGColor.m */,
59EB75A923905F6F00F5AE63 /* IJSVGColorList.h */,
59EB757123905F6C00F5AE63 /* IJSVGColorList.m */,
59EB75C723905F7100F5AE63 /* IJSVGCommand.h */,
59EB75A023905F6E00F5AE63 /* IJSVGCommand.m */,
59EB75B723905F7000F5AE63 /* IJSVGCommandClose.h */,
59EB75C623905F7100F5AE63 /* IJSVGCommandClose.m */,
59EB759C23905F6E00F5AE63 /* IJSVGCommandCurve.h */,
59EB759823905F6E00F5AE63 /* IJSVGCommandCurve.m */,
59EB759E23905F6E00F5AE63 /* IJSVGCommandEllipticalArc.h */,
59EB75CB23905F7200F5AE63 /* IJSVGCommandEllipticalArc.m */,
59EB759523905F6D00F5AE63 /* IJSVGCommandHorizontalLine.h */,
59EB758723905F6C00F5AE63 /* IJSVGCommandHorizontalLine.m */,
59EB756823905F6B00F5AE63 /* IJSVGCommandLineTo.h */,
59EB75AE23905F6F00F5AE63 /* IJSVGCommandLineTo.m */,
59EB75AF23905F6F00F5AE63 /* IJSVGCommandMove.h */,
59EB759923905F6E00F5AE63 /* IJSVGCommandMove.m */,
59EB757E23905F6C00F5AE63 /* IJSVGCommandQuadraticCurve.h */,
59EB756C23905F6B00F5AE63 /* IJSVGCommandQuadraticCurve.m */,
59EB757023905F6C00F5AE63 /* IJSVGCommandSmoothCurve.h */,
59EB75A823905F6F00F5AE63 /* IJSVGCommandSmoothCurve.m */,
59EB75CA23905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.h */,
59EB75C823905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.m */,
59EB756D23905F6C00F5AE63 /* IJSVGCommandVerticalLine.h */,
59EB759123905F6D00F5AE63 /* IJSVGCommandVerticalLine.m */,
59EB758623905F6C00F5AE63 /* IJSVGDef.h */,
59EB756923905F6B00F5AE63 /* IJSVGDef.m */,
59EB758423905F6C00F5AE63 /* IJSVGError.h */,
59EB75D423905F7300F5AE63 /* IJSVGExporter.h */,
59EB75BD23905F7000F5AE63 /* IJSVGExporter.m */,
59EB75B223905F6F00F5AE63 /* IJSVGExporterPathInstruction.h */,
59EB75CF23905F7200F5AE63 /* IJSVGExporterPathInstruction.m */,
59EB758823905F6D00F5AE63 /* IJSVGFontConverter.h */,
59EB757C23905F6C00F5AE63 /* IJSVGFontConverter.m */,
59EB75CE23905F7200F5AE63 /* IJSVGForeignObject.h */,
59EB75C923905F7200F5AE63 /* IJSVGForeignObject.m */,
59EB75AB23905F6F00F5AE63 /* IJSVGGradient.h */,
59EB75D223905F7300F5AE63 /* IJSVGGradient.m */,
59EB756623905F6B00F5AE63 /* IJSVGGradientLayer.h */,
59EB758F23905F6D00F5AE63 /* IJSVGGradientLayer.m */,
59EB757323905F6C00F5AE63 /* IJSVGGradientUnitLength.h */,
59EB75B923905F7000F5AE63 /* IJSVGGradientUnitLength.m */,
59EB758B23905F6D00F5AE63 /* IJSVGGroup.h */,
59EB75CC23905F7200F5AE63 /* IJSVGGroup.m */,
59EB75AD23905F6F00F5AE63 /* IJSVGGroupLayer.h */,
59EB758223905F6C00F5AE63 /* IJSVGGroupLayer.m */,
59EB75B523905F7000F5AE63 /* IJSVGImage.h */,
59EB757623905F6C00F5AE63 /* IJSVGImage.m */,
59EB75D023905F7200F5AE63 /* IJSVGImageLayer.h */,
59EB75C523905F7100F5AE63 /* IJSVGImageLayer.m */,
59EB75A323905F6E00F5AE63 /* IJSVGImageRep.h */,
59EB757D23905F6C00F5AE63 /* IJSVGImageRep.m */,
59EB756523905F6B00F5AE63 /* IJSVGLayer.h */,
59EB757B23905F6C00F5AE63 /* IJSVGLayer.m */,
59EB75BC23905F7000F5AE63 /* IJSVGLayerTree.h */,
59EB759023905F6D00F5AE63 /* IJSVGLayerTree.m */,
59EB759F23905F6E00F5AE63 /* IJSVGLinearGradient.h */,
59EB75C223905F7100F5AE63 /* IJSVGLinearGradient.m */,
59EB75B623905F7000F5AE63 /* IJSVGMath.h */,
59EB75B123905F6F00F5AE63 /* IJSVGMath.m */,
59EB759223905F6D00F5AE63 /* IJSVGNode.h */,
59EB759623905F6D00F5AE63 /* IJSVGNode.m */,
59EB75A723905F6F00F5AE63 /* IJSVGParser.h */,
59EB75A523905F6E00F5AE63 /* IJSVGParser.m */,
59EB759D23905F6E00F5AE63 /* IJSVGPath.h */,
59EB758A23905F6D00F5AE63 /* IJSVGPath.m */,
59EB75BB23905F7000F5AE63 /* IJSVGPattern.h */,
59EB75AA23905F6F00F5AE63 /* IJSVGPattern.m */,
59EB75BF23905F7000F5AE63 /* IJSVGPatternLayer.h */,
59EB758C23905F6D00F5AE63 /* IJSVGPatternLayer.m */,
59EB757223905F6C00F5AE63 /* IJSVGRadialGradient.h */,
59EB75A623905F6F00F5AE63 /* IJSVGRadialGradient.m */,
59EB75D323905F7300F5AE63 /* IJSVGRendering.h */,
59EB75D523905F7300F5AE63 /* IJSVGRendering.m */,
59EB75A123905F6E00F5AE63 /* IJSVGRenderingStyle.h */,
59EB758D23905F6D00F5AE63 /* IJSVGRenderingStyle.m */,
59EB759723905F6D00F5AE63 /* IJSVGShapeLayer.h */,
59EB757A23905F6C00F5AE63 /* IJSVGShapeLayer.m */,
59EB75B823905F7000F5AE63 /* IJSVGStringAdditions.h */,
59EB757823905F6C00F5AE63 /* IJSVGStringAdditions.m */,
59EB75A423905F6E00F5AE63 /* IJSVGStrokeLayer.h */,
59EB757423905F6C00F5AE63 /* IJSVGStrokeLayer.m */,
59EB75AC23905F6F00F5AE63 /* IJSVGStyle.h */,
59EB757523905F6C00F5AE63 /* IJSVGStyle.m */,
59EB756F23905F6C00F5AE63 /* IJSVGStyleSheet.h */,
59EB75D123905F7300F5AE63 /* IJSVGStyleSheet.m */,
59EB759B23905F6E00F5AE63 /* IJSVGStyleSheetRule.h */,
59EB756723905F6B00F5AE63 /* IJSVGStyleSheetRule.m */,
59EB759A23905F6E00F5AE63 /* IJSVGStyleSheetSelector.h */,
59EB75C423905F7100F5AE63 /* IJSVGStyleSheetSelector.m */,
59EB757F23905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.h */,
59EB758123905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.m */,
59EB756B23905F6B00F5AE63 /* IJSVGText.h */,
59EB75C023905F7100F5AE63 /* IJSVGText.m */,
59EB757923905F6C00F5AE63 /* IJSVGTransaction.h */,
59EB75B323905F6F00F5AE63 /* IJSVGTransaction.m */,
59EB75B023905F6F00F5AE63 /* IJSVGTransform.h */,
59EB75B423905F6F00F5AE63 /* IJSVGTransform.m */,
59EB757723905F6C00F5AE63 /* IJSVGUnitLength.h */,
59EB75BA23905F7000F5AE63 /* IJSVGUnitLength.m */,
59EB759423905F6D00F5AE63 /* IJSVGUtils.h */,
59EB758023905F6C00F5AE63 /* IJSVGUtils.m */,
59EB75CD23905F7200F5AE63 /* IJSVGView.h */,
59EB75C123905F7100F5AE63 /* IJSVGView.m */,
59EB756E23905F6C00F5AE63 /* IJSVGWriter.h */,
59EB758923905F6D00F5AE63 /* IJSVGWriter.m */,
);
path = Core;
sourceTree = "<group>";
};
59EB756423905F3100F5AE63 /* Source */ = {
isa = PBXGroup;
children = (
59DD1FD123A22CFD00E28C56 /* Core */,
592ABBEB2397A11800F44380 /* Additions */,
592ABBEA2397A10000F44380 /* Rendering */,
592ABBE92397A08500F44380 /* Exporter */,
592ABBE82397A06800F44380 /* Utils */,
592ABBE72397A02900F44380 /* Nodes */,
592ABBE62397A00C00F44380 /* Parsing */,
592ABBE523979FE100F44380 /* Layers */,
592ABBE423979FD200F44380 /* Colors */,
592ABBE323979FBB00F44380 /* Stylesheets */,
592ABBE223979F9B00F44380 /* Commands */,
);
path = Source;
sourceTree = "<group>";
};
@@ -457,7 +545,6 @@
59EB75E823905F7300F5AE63 /* IJSVGUnitLength.h in Headers */,
59EB762723905F7300F5AE63 /* IJSVGMath.h in Headers */,
59EB761523905F7300F5AE63 /* IJSVGStrokeLayer.h in Headers */,
59EB762F23905F7300F5AE63 /* IJSVGCache.h in Headers */,
59EB75DE23905F7300F5AE63 /* IJSVGCommandVerticalLine.h in Headers */,
59EB764123905F7300F5AE63 /* IJSVGImageLayer.h in Headers */,
59EB75E023905F7300F5AE63 /* IJSVGStyleSheet.h in Headers */,
@@ -480,6 +567,7 @@
59EB761E23905F7300F5AE63 /* IJSVGGroupLayer.h in Headers */,
59EB761D23905F7300F5AE63 /* IJSVGStyle.h in Headers */,
59EB764523905F7300F5AE63 /* IJSVGExporter.h in Headers */,
59E7CFAF23B148600077D599 /* IJSVGCommandParser.h in Headers */,
59EB762823905F7300F5AE63 /* IJSVGCommandClose.h in Headers */,
59EB75E423905F7300F5AE63 /* IJSVGGradientUnitLength.h in Headers */,
59EB762D23905F7300F5AE63 /* IJSVGLayerTree.h in Headers */,
@@ -573,10 +661,10 @@
59EB75E523905F7300F5AE63 /* IJSVGStrokeLayer.m in Sources */,
59EB763223905F7300F5AE63 /* IJSVGView.m in Sources */,
59EB763523905F7300F5AE63 /* IJSVGStyleSheetSelector.m in Sources */,
59E7CFB023B148600077D599 /* IJSVGCommandParser.m in Sources */,
59EB760723905F7300F5AE63 /* IJSVGNode.m in Sources */,
59EB75E923905F7300F5AE63 /* IJSVGStringAdditions.m in Sources */,
59EB761723905F7300F5AE63 /* IJSVGRadialGradient.m in Sources */,
59EB760423905F7300F5AE63 /* IJSVGCache.m in Sources */,
59EB75E223905F7300F5AE63 /* IJSVGColorList.m in Sources */,
59EB75ED23905F7300F5AE63 /* IJSVGFontConverter.m in Sources */,
59EB763C23905F7300F5AE63 /* IJSVGCommandEllipticalArc.m in Sources */,
@@ -740,6 +828,7 @@
CLANG_WARN_STRICT_PROTOTYPES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2;
DEFINES_MODULE = NO;
DEVELOPMENT_TEAM = 9KTR4W9XX6;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -752,7 +841,7 @@
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 2.1;
MARKETING_VERSION = 2.2.0;
PRODUCT_BUNDLE_IDENTIFIER = com.iconjar.ijsvg;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
@@ -767,6 +856,7 @@
CLANG_WARN_STRICT_PROTOTYPES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2;
DEFINES_MODULE = NO;
DEVELOPMENT_TEAM = 9KTR4W9XX6;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -779,7 +869,7 @@
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 2.1;
MARKETING_VERSION = 2.2.0;
PRODUCT_BUNDLE_IDENTIFIER = com.iconjar.ijsvg;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1120"
LastUpgradeVersion = "1130"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -7,7 +7,7 @@
<key>IJSVG.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
<integer>2</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
@@ -14,4 +14,6 @@
- (void)addQuadCurveToPoint:(NSPoint)aPoint
controlPoint:(NSPoint)cp;
- (CGPathRef)newCGPathRef:(BOOL)autoClose;
@end
@@ -1,84 +1,33 @@
//
// IJSVGPath.m
// IJSVGBezierPathAdditions.m
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGGroup.h"
#import "IJSVGPath.h"
#import "IJSVGBezierPathAdditions.h"
@implementation IJSVGPath
@implementation NSBezierPath (IJSVGAdditions)
@synthesize path;
@synthesize subpath;
@synthesize lastControlPoint;
@synthesize CGPath = _CGPath;
- (void)dealloc
- (void)addQuadCurveToPoint:(CGPoint)QP2
controlPoint:(CGPoint)QP1
{
if(_CGPath != nil) {
CGPathRelease(_CGPath);
_CGPath = nil;
}
if (subpath != nil) {
(void)([subpath release]), subpath = nil;
}
[super dealloc];
CGPoint QP0 = [self currentPoint];
CGPoint CP3 = QP2;
CGPoint CP1 = CGPointMake(QP0.x + ((2.0 / 3.0) * (QP1.x - QP0.x)), QP0.y + ((2.0 / 3.0) * (QP1.y - QP0.y)));
CGPoint CP2 = CGPointMake(QP2.x + (2.0 / 3.0) * (QP1.x - QP2.x), QP2.y + (2.0 / 3.0) * (QP1.y - QP2.y));
[self curveToPoint:CP3
controlPoint1:CP1
controlPoint2:CP2];
}
- (id)init
{
if ((self = [super init]) != nil) {
subpath = NSBezierPath.bezierPath.retain;
path = subpath; // for legacy use
}
return self;
}
- (id)copyWithZone:(NSZone*)zone
{
IJSVGPath* node = [super copyWithZone:zone];
[node overwritePath:self.path];
return node;
}
- (NSPoint)currentPoint
{
return [subpath currentPoint];
}
- (NSBezierPath*)currentSubpath
{
return subpath;
}
- (void)close
{
[subpath closePath];
}
- (CGPathRef)CGPath
{
if(_CGPath == nil) {
_CGPath = [self newPathRefByAutoClosingPath:NO];
}
return _CGPath;
}
- (void)overwritePath:(NSBezierPath*)aPath
{
(void)([subpath release]), subpath = nil;
subpath = [aPath retain];
path = subpath;
}
- (CGPathRef)newPathRefByAutoClosingPath:(BOOL)autoClose
- (CGPathRef)newCGPathRef:(BOOL)autoClose
{
NSInteger i = 0;
NSInteger numElements = self.path.elementCount;
NSBezierPath* bezPath = self.path;
NSInteger numElements = self.elementCount;
NSBezierPath* bezPath = self;
// nothing to return
if (numElements == 0) {
@@ -10,7 +10,7 @@
@interface NSString (IJSVGAdditions)
- (NSArray<NSString *> *)ijsvg_componentsSeparatedByChars:(char *)aChar;
- (NSArray<NSString*>*)ijsvg_componentsSeparatedByChars:(const char*)aChar;
- (BOOL)ijsvg_isNumeric;
- (BOOL)ijsvg_containsAlpha;
- (NSArray*)ijsvg_componentsSplitByWhiteSpace;
@@ -10,7 +10,7 @@
@implementation NSString (IJSVGAdditions)
- (NSArray<NSString*>*)ijsvg_componentsSeparatedByChars:(char*)aChar
- (NSArray<NSString*>*)ijsvg_componentsSeparatedByChars:(const char*)aChar
{
NSMutableArray* comp = [[[NSMutableArray alloc] init] autorelease];
NSInteger length = self.length;
@@ -18,25 +18,13 @@
NSInteger ind = 0;
BOOL startedString = NO;
// block for easy comparison
NSUInteger aLength = strlen(aChar);
BOOL (^charsContainsChar)(char anotherChar) = ^(char anotherChar) {
for (NSInteger i = 0; i < aLength; i++) {
if (aChar[i] == anotherChar) {
return YES;
}
}
return NO;
};
const char* buffer = self.UTF8String;
for (NSInteger i = 0; i < length; i++) {
// the char
unichar theChar = [self characterAtIndex:i];
unichar theChar = buffer[i];
// start the buffer
BOOL isEqualToChar = charsContainsChar(theChar);
BOOL isEqualToChar = strchr(aChar, theChar) != NULL;
if (isEqualToChar == NO) {
startedString = YES;
chars[ind++] = theChar;
@@ -48,11 +36,10 @@
// append the comp
[comp addObject:[NSString stringWithCharacters:chars length:ind]];
free(chars);
// restart and realloc the memory
ind = 0;
chars = (unichar*)calloc(sizeof(unichar), self.length);
chars = memset(chars, '\0', sizeof(unichar) * ind);
}
}
free(chars);
@@ -258,12 +258,13 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
}
// is simply a clear color, dont fill
if ([[string lowercaseString] isEqualToString:@"none"]) {
if ([string.lowercaseString isEqualToString:@"none"] ||
[string.lowercaseString isEqualToString:@"transparent"]) {
return [self computeColorSpace:NSColor.clearColor];
}
// is it RGB?
if ([[string substringToIndex:3] isEqualToString:@"rgb"]) {
if ([string hasPrefix:@"rgb"] == YES) {
NSRange range = [IJSVGUtils rangeOfParentheses:string];
NSString* rgbString = [string substringWithRange:range];
NSArray* parts = [rgbString ijsvg_componentsSeparatedByChars:","];
@@ -278,7 +279,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
}
// is it HSL?
if ([[string substringToIndex:3] isEqualToString:@"hsl"]) {
if ([string hasPrefix:@"hsl"]) {
NSInteger count = 0;
CGFloat* params = [IJSVGUtils commandParameters:string
count:&count];
@@ -309,7 +310,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
+ (NSColor*)colorFromPredefinedColorName:(NSString*)name
{
NSNumber* hex = nil;
name = [name.lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
name = [name.lowercaseString stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
if ((hex = _colorTree[name]) == nil) {
return nil;
}
@@ -384,8 +385,8 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
}
// note the %g, CSS alpha is 0 to 1, not 0 - 100, my bad!
return [NSString stringWithFormat:@"rgba(%d,%d,%d,%g)", red, green, blue,
((float)alpha / 100.f)];
return [NSString stringWithFormat:@"rgba(%d,%d,%d,%@)", red, green, blue,
IJSVGShortFloatString((float)alpha / 100.f)];
}
+ (NSString*)colorNameFromPredefinedColor:(IJSVGPredefinedColor)color
@@ -701,8 +702,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
+ (BOOL)isColor:(NSString*)string
{
return [[string substringToIndex:1] isEqualToString:@"#"] ||
[[string substringToIndex:3] isEqualToString:@"rgb"];
return [string hasPrefix:@"#"] || [string hasPrefix:@"rgb"];
}
+ (BOOL)isHex:(NSString*)string
@@ -764,7 +764,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
return nil;
}
if ([[string substringToIndex:1] isEqualToString:@"#"]) {
if ([string hasPrefix:@"#"] == YES) {
string = [string substringFromIndex:1];
}
@@ -6,22 +6,23 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandParser.h"
#import "IJSVGPath.h"
#import <Foundation/Foundation.h>
static const NSInteger IJSVGCustomVariableParameterCount = NSNotFound;
typedef NS_ENUM(NSInteger, IJSVGCommandType) {
IJSVGCommandTypeAbsolute,
IJSVGCommandTypeRelative
kIJSVGCommandTypeAbsolute,
kIJSVGCommandTypeRelative
};
@interface IJSVGCommand : NSObject {
NSString* commandString;
NSString* command;
char command;
CGFloat* parameters;
NSInteger parameterCount;
NSMutableArray* subCommands;
NSArray<IJSVGCommand*>* subCommands;
NSInteger requiredParameters;
IJSVGCommandType type;
IJSVGCommand* previousCommand;
@@ -30,12 +31,11 @@ typedef NS_ENUM(NSInteger, IJSVGCommandType) {
}
@property (nonatomic, copy) NSString* commandString;
@property (nonatomic, copy) NSString* command;
@property (nonatomic, assign) char command;
@property (nonatomic, assign) CGFloat* parameters;
@property (nonatomic, assign) NSInteger parameterCount;
@property (nonatomic, assign) NSInteger requiredParameters;
@property (nonatomic, assign) IJSVGCommandType type;
@property (nonatomic, retain) NSMutableArray<IJSVGCommand*>* subCommands;
@property (nonatomic, retain) NSArray<IJSVGCommand*>* subCommands;
@property (nonatomic, assign) IJSVGCommand* previousCommand;
@property (nonatomic, assign) BOOL isSubCommand;
@@ -43,6 +43,7 @@ typedef NS_ENUM(NSInteger, IJSVGCommandType) {
+ (NSInteger)requiredParameterCount;
+ (NSPoint)readCoordinatePair:(CGFloat*)pairs
index:(NSInteger)index;
+ (IJSVGPathDataSequence*)pathDataSequence;
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
@@ -54,8 +55,10 @@ typedef NS_ENUM(NSInteger, IJSVGCommandType) {
intoArray:(NSMutableArray<IJSVGCommand*>*)commands
parentCommand:(IJSVGCommand*)parentCommand;
- (id)initWithCommandString:(NSString*)commandString;
- (id)initWithCommandString:(NSString*)str
dataStream:(IJSVGPathDataStream*)dataStream;
- (IJSVGCommand*)subcommandWithParameters:(CGFloat*)subParams
paramCount:(NSInteger)paramCount
previousCommand:(IJSVGCommand*)command;
- (CGFloat)readFloat;
@@ -27,7 +27,6 @@
@synthesize parameterCount;
@synthesize parameters;
@synthesize subCommands;
@synthesize requiredParameters;
@synthesize type;
@synthesize previousCommand;
@synthesize isSubCommand;
@@ -42,6 +41,11 @@
return 1;
}
+ (IJSVGPathDataSequence*)pathDataSequence
{
return NULL;
}
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
@@ -100,80 +104,80 @@
- (void)dealloc
{
(void)([commandString release]), commandString = nil;
(void)([command release]), command = nil;
(void)([subCommands release]), subCommands = nil;
(void)(free(parameters)), parameters = nil;
if (parameters) {
(void)(free(parameters)), parameters = nil;
}
[super dealloc];
}
- (id)initWithCommandString:(NSString*)str
dataStream:(IJSVGPathDataStream*)dataStream
{
if ((self = [super init]) != nil) {
// work out the basics
_currentIndex = 0;
command = [[str substringToIndex:1] copy];
type = [IJSVGUtils typeForCommandString:self.command];
parameters = [IJSVGUtils commandParameters:str
count:&parameterCount];
requiredParameters = [self.class requiredParameterCount];
command = [str characterAtIndex:0];
type = [IJSVGUtils typeForCommandChar:command];
NSInteger sets = 0;
NSInteger paramCount = [self.class requiredParameterCount];
IJSVGPathDataSequence* sequence = [self.class pathDataSequence];
parameters = IJSVGParsePathDataStreamSequence(str.UTF8String, str.length,
dataStream, sequence, [self.class requiredParameterCount], &sets);
// check what required params we need
if (requiredParameters == IJSVGCustomVariableParameterCount) {
// looks like we require variable params
subCommands = [[NSMutableArray alloc] init];
// parse the custom params
[self.class parseParams:parameters
paramCount:parameterCount
intoArray:subCommands
parentCommand:self];
if (sets <= 1) {
CGFloat* subParams = [self parametersFromIndexOffset:0];
IJSVGCommand* command = [self subcommandWithParameters:subParams
paramCount:paramCount
previousCommand:nil];
subCommands = @[ command ].retain;
} else {
// now work out the sets of parameters we have
// each command could have a series of subcommands
// if there is a multiple of commands in a command
// then we need to work those out...
NSInteger sets = 1;
if (self.requiredParameters != 0) {
sets = (self.parameterCount / self.requiredParameters);
}
subCommands = [[NSMutableArray alloc] initWithCapacity:sets];
NSMutableArray<IJSVGCommand*>* subCommandArray = nil;
subCommandArray = [[NSMutableArray alloc] initWithCapacity:sets].autorelease;
// interate over the sets
IJSVGCommand* lastCommand = nil;
for (NSInteger i = 0; i < sets; i++) {
// memory for this will be handled by the created subcommand
CGFloat* subParams = 0;
if (self.requiredParameters != 0) {
subParams = (CGFloat*)malloc(self.requiredParameters * sizeof(CGFloat));
for (NSInteger p = 0; p < self.requiredParameters; p++) {
subParams[p] = self.parameters[i * self.requiredParameters + p];
}
}
CGFloat* subParams = [self parametersFromIndexOffset:i];
// generate the subcommand
IJSVGCommand* command = [self subcommandWithParameters:subParams
paramCount:paramCount
previousCommand:lastCommand];
// make sure we assign the last command or hell breaks
// lose and the firey demons will run wild, namely, commands will break
// if they are multiples of a set
lastCommand = command;
// add it to our tree
[subCommands addObject:command];
[subCommandArray addObject:command];
}
// store the retained value
subCommands = subCommandArray.copy;
}
}
return self;
}
- (CGFloat*)parametersFromIndexOffset:(NSInteger)index
{
CGFloat* subParams = 0;
NSInteger req = [self.class requiredParameterCount];
if (req != 0) {
subParams = (CGFloat*)malloc(req * sizeof(CGFloat));
memcpy(subParams, &self.parameters[index * req], sizeof(CGFloat) * req);
}
return subParams;
}
- (IJSVGCommand*)subcommandWithParameters:(CGFloat*)subParams
paramCount:(NSInteger)paramCount
previousCommand:(IJSVGCommand*)aPreviousCommand
{
// create a subcommand per set
IJSVGCommand* c = [[[self.class alloc] init] autorelease];
c.parameterCount = self.requiredParameters;
c.parameterCount = paramCount;
c.parameters = subParams;
c.type = self.type;
c.command = self.command;
@@ -22,15 +22,15 @@
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
if (type == IJSVGCommandTypeAbsolute) {
[[path currentSubpath] curveToPoint:NSMakePoint(params[4], params[5])
controlPoint1:NSMakePoint(params[0], params[1])
controlPoint2:NSMakePoint(params[2], params[3])];
if (type == kIJSVGCommandTypeAbsolute) {
[path.path curveToPoint:NSMakePoint(params[4], params[5])
controlPoint1:NSMakePoint(params[0], params[1])
controlPoint2:NSMakePoint(params[2], params[3])];
return;
}
[[path currentSubpath] relativeCurveToPoint:NSMakePoint(params[4], params[5])
controlPoint1:NSMakePoint(params[0], params[1])
controlPoint2:NSMakePoint(params[2], params[3])];
[path.path relativeCurveToPoint:NSMakePoint(params[4], params[5])
controlPoint1:NSMakePoint(params[0], params[1])
controlPoint2:NSMakePoint(params[2], params[3])];
}
@end
@@ -11,11 +11,28 @@
@implementation IJSVGCommandEllipticalArc
static IJSVGPathDataSequence* _sequence;
+ (NSInteger)requiredParameterCount
{
return 7;
}
+ (IJSVGPathDataSequence*)pathDataSequence
{
if(_sequence == NULL) {
_sequence = (IJSVGPathDataSequence*)malloc(sizeof(IJSVGPathDataSequence) * 7);
_sequence[0] = kIJSVGPathDataSequenceTypeFloat;
_sequence[1] = kIJSVGPathDataSequenceTypeFloat;
_sequence[2] = kIJSVGPathDataSequenceTypeFloat;
_sequence[3] = kIJSVGPathDataSequenceTypeFlag;
_sequence[4] = kIJSVGPathDataSequenceTypeFlag;
_sequence[5] = kIJSVGPathDataSequenceTypeFloat;
_sequence[6] = kIJSVGPathDataSequenceTypeFloat;
}
return _sequence;
}
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
@@ -36,7 +53,7 @@
sweepFlag = [currentCommand readBOOL];
arcEndPoint = [currentCommand readPoint];
if (type == IJSVGCommandTypeRelative) {
if (type == kIJSVGCommandTypeRelative) {
arcEndPoint.x += path.currentPoint.x;
arcEndPoint.y += path.currentPoint.y;
}
@@ -75,33 +92,33 @@
NSAffineTransform* trans = NSAffineTransform.transform;
[trans translateXBy:-centerPoint.x yBy:-centerPoint.y];
[path.currentSubpath transformUsingAffineTransform:trans];
[path.path transformUsingAffineTransform:trans];
trans = NSAffineTransform.transform;
[trans rotateByRadians:-xAxisRotation];
[path.currentSubpath transformUsingAffineTransform:trans];
[path.path transformUsingAffineTransform:trans];
trans = NSAffineTransform.transform;
[trans scaleXBy:(1 / scale.x) yBy:(1 / scale.y)];
[path.currentSubpath transformUsingAffineTransform:trans];
[path.path transformUsingAffineTransform:trans];
[path.currentSubpath appendBezierPathWithArcWithCenter:NSZeroPoint
radius:radius
startAngle:radians_to_degrees(startAngle)
endAngle:radians_to_degrees(startAngle + angleDelta)
clockwise:!sweepFlag];
[path.path appendBezierPathWithArcWithCenter:NSZeroPoint
radius:radius
startAngle:radians_to_degrees(startAngle)
endAngle:radians_to_degrees(startAngle + angleDelta)
clockwise:!sweepFlag];
trans = NSAffineTransform.transform;
[trans scaleXBy:scale.x yBy:scale.y];
[path.currentSubpath transformUsingAffineTransform:trans];
[path.path transformUsingAffineTransform:trans];
trans = NSAffineTransform.transform;
[trans rotateByRadians:xAxisRotation];
[path.currentSubpath transformUsingAffineTransform:trans];
[path.path transformUsingAffineTransform:trans];
trans = NSAffineTransform.transform;
[trans translateXBy:centerPoint.x yBy:centerPoint.y];
[path.currentSubpath transformUsingAffineTransform:trans];
[path.path transformUsingAffineTransform:trans];
}
@end
@@ -22,11 +22,11 @@
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
if (type == IJSVGCommandTypeAbsolute) {
[[path currentSubpath] lineToPoint:NSMakePoint(params[0], [path currentSubpath].currentPoint.y)];
if (type == kIJSVGCommandTypeAbsolute) {
[path.path lineToPoint:NSMakePoint(params[0], path.currentPoint.y)];
return;
}
[[path currentSubpath] relativeLineToPoint:NSMakePoint(params[0], 0.f)];
[path.path relativeLineToPoint:NSMakePoint(params[0], 0.f)];
}
@end
@@ -22,13 +22,13 @@
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
if (type == IJSVGCommandTypeAbsolute) {
[[path currentSubpath] lineToPoint:NSMakePoint(params[0], params[1])];
if (type == kIJSVGCommandTypeAbsolute) {
[path.path lineToPoint:NSMakePoint(params[0], params[1])];
return;
}
NSPoint point = NSMakePoint([path currentSubpath].currentPoint.x + params[0],
[path currentSubpath].currentPoint.y + params[1]);
[[path currentSubpath] lineToPoint:point];
NSPoint point = NSMakePoint(path.currentPoint.x + params[0],
path.currentPoint.y + params[1]);
[path.path lineToPoint:point];
}
@end
@@ -36,15 +36,15 @@
}
// actual move to command
if (type == IJSVGCommandTypeAbsolute) {
[[path currentSubpath] moveToPoint:NSMakePoint(params[0], params[1])];
if (type == kIJSVGCommandTypeAbsolute) {
[path.path moveToPoint:NSMakePoint(params[0], params[1])];
return;
}
@try {
[[path currentSubpath] relativeMoveToPoint:NSMakePoint(params[0], params[1])];
[path.path relativeMoveToPoint:NSMakePoint(params[0], params[1])];
}
@catch (NSException* exception) {
[[path currentSubpath] moveToPoint:NSMakePoint(params[0], params[1])];
[path.path moveToPoint:NSMakePoint(params[0], params[1])];
}
}
@@ -23,13 +23,13 @@
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
if (type == IJSVGCommandTypeAbsolute) {
[[path currentSubpath] addQuadCurveToPoint:NSMakePoint(params[2], params[3])
controlPoint:NSMakePoint(params[0], params[1])];
if (type == kIJSVGCommandTypeAbsolute) {
[path.path addQuadCurveToPoint:NSMakePoint(params[2], params[3])
controlPoint:NSMakePoint(params[0], params[1])];
return;
}
[[path currentSubpath] addQuadCurveToPoint:NSMakePoint([path currentSubpath].currentPoint.x + params[2], [path currentSubpath].currentPoint.y + params[3])
controlPoint:NSMakePoint([path currentSubpath].currentPoint.x + params[0], [path currentSubpath].currentPoint.y + params[1])];
[path.path addQuadCurveToPoint:NSMakePoint(path.currentPoint.x + params[2], path.currentPoint.y + params[3])
controlPoint:NSMakePoint(path.currentPoint.x + params[0], path.currentPoint.y + params[1])];
}
@end
@@ -0,0 +1,64 @@
//
// IJSVGCommandSmoothCurve.m
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandCurve.h"
#import "IJSVGCommandSmoothCurve.h"
#import "IJSVGUtils.h"
@implementation IJSVGCommandSmoothCurve
+ (NSInteger)requiredParameterCount
{
return 4;
}
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
NSPoint firstControl = NSMakePoint(path.currentPoint.x, path.currentPoint.y);
if (command != nil) {
if (command.class == [IJSVGCommandCurve class] || command.class == self.class) {
if (command.class == [IJSVGCommandCurve class]) {
if (command.type == kIJSVGCommandTypeAbsolute) {
firstControl = NSMakePoint(-1 * command.parameters[2] + 2 * path.currentPoint.x,
-1 * command.parameters[3] + 2 * path.currentPoint.y);
} else {
NSPoint oldPoint = NSMakePoint(path.currentPoint.x - command.parameters[4],
path.currentPoint.y - command.parameters[5]);
firstControl = NSMakePoint(-1 * (command.parameters[2] + oldPoint.x) + 2 * path.currentPoint.x,
-1 * (command.parameters[3] + oldPoint.y) + 2 * path.currentPoint.y);
}
} else {
if (command.type == kIJSVGCommandTypeAbsolute) {
firstControl = NSMakePoint(-1 * command.parameters[0] + 2 * path.currentPoint.x,
-1 * command.parameters[1] + 2 * path.currentPoint.y);
} else {
NSPoint oldPoint = NSMakePoint(path.currentPoint.x - command.parameters[2],
path.currentPoint.y - command.parameters[3]);
firstControl = NSMakePoint(-1 * (command.parameters[0] + oldPoint.x) + 2 * path.currentPoint.x,
-1 * (command.parameters[1] + oldPoint.y) + 2 * path.currentPoint.y);
}
}
}
}
if (type == kIJSVGCommandTypeAbsolute) {
[path.path curveToPoint:NSMakePoint(params[2], params[3])
controlPoint1:NSMakePoint(firstControl.x, firstControl.y)
controlPoint2:NSMakePoint(params[0], params[1])];
return;
}
[path.path curveToPoint:NSMakePoint(path.currentPoint.x + params[2], path.currentPoint.y + params[3])
controlPoint1:NSMakePoint(firstControl.x, firstControl.y)
controlPoint2:NSMakePoint(path.currentPoint.x + params[0], path.currentPoint.y + params[1])];
}
@end
@@ -24,33 +24,33 @@
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
NSPoint commandPoint = NSMakePoint([path currentSubpath].currentPoint.x, [path currentSubpath].currentPoint.y);
NSPoint commandPoint = NSMakePoint(path.currentPoint.x, path.currentPoint.y);
if (command != nil) {
if (command.class == IJSVGCommandQuadraticCurve.class) {
// quadratic curve
if (command.type == IJSVGCommandTypeAbsolute) {
commandPoint = NSMakePoint(-1 * command.parameters[0] + 2 * [path currentSubpath].currentPoint.x,
-1 * command.parameters[1] + 2 * [path currentSubpath].currentPoint.y);
if (command.type == kIJSVGCommandTypeAbsolute) {
commandPoint = NSMakePoint(-1 * command.parameters[0] + 2 * path.currentPoint.x,
-1 * command.parameters[1] + 2 * path.currentPoint.y);
} else {
NSPoint oldPoint = CGPointMake([path currentSubpath].currentPoint.x - command.parameters[2],
[path currentSubpath].currentPoint.y - command.parameters[3]);
commandPoint = CGPointMake(-1 * (command.parameters[0] + oldPoint.x) + 2 * ([path currentSubpath].currentPoint.x),
-1 * (command.parameters[1] + oldPoint.y) + 2 * [path currentSubpath].currentPoint.y);
NSPoint oldPoint = CGPointMake(path.currentPoint.x - command.parameters[2],
path.currentPoint.y - command.parameters[3]);
commandPoint = CGPointMake(-1 * (command.parameters[0] + oldPoint.x) + 2 * (path.currentPoint.x),
-1 * (command.parameters[1] + oldPoint.y) + 2 * path.currentPoint.y);
}
} else if (command.class == self.class) {
// smooth quadratic curve
commandPoint = CGPointMake(-1 * (path.lastControlPoint.x) + 2 * ([path currentSubpath].currentPoint.x),
-1 * (path.lastControlPoint.y) + 2 * [path currentSubpath].currentPoint.y);
commandPoint = CGPointMake(-1 * (path.lastControlPoint.x) + 2 * (path.currentPoint.x),
-1 * (path.lastControlPoint.y) + 2 * path.currentPoint.y);
}
}
path.lastControlPoint = commandPoint;
if (type == IJSVGCommandTypeAbsolute) {
[[path currentSubpath] addQuadCurveToPoint:NSMakePoint(params[0], params[1])
controlPoint:commandPoint];
if (type == kIJSVGCommandTypeAbsolute) {
[path.path addQuadCurveToPoint:NSMakePoint(params[0], params[1])
controlPoint:commandPoint];
return;
}
[[path currentSubpath] addQuadCurveToPoint:NSMakePoint([path currentSubpath].currentPoint.x + params[0], [path currentSubpath].currentPoint.y + params[1])
controlPoint:commandPoint];
[path.path addQuadCurveToPoint:NSMakePoint(path.currentPoint.x + params[0], path.currentPoint.y + params[1])
controlPoint:commandPoint];
}
@end
@@ -22,11 +22,11 @@
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
if (type == IJSVGCommandTypeAbsolute) {
[[path currentSubpath] lineToPoint:NSMakePoint([path currentSubpath].currentPoint.x, params[0])];
if (type == kIJSVGCommandTypeAbsolute) {
[path.path lineToPoint:NSMakePoint(path.currentPoint.x, params[0])];
return;
}
[[path currentSubpath] relativeLineToPoint:NSMakePoint(0.f, params[0])];
[path.path relativeLineToPoint:NSMakePoint(0.f, params[0])];
}
@end
@@ -16,13 +16,10 @@
#import "IJSVGParser.h"
#import "IJSVGRendering.h"
#import "IJSVGRenderingStyle.h"
#import "IJSVGTransaction.h"
#import <Foundation/Foundation.h>
@class IJSVG;
@class IJSVGQuartzRenderer;
void IJSVGBeginTransactionLock(void);
void IJSVGEndTransactionLock(void);
@protocol IJSVGDelegate <NSObject, IJSVGParserDelegate>
@@ -48,11 +45,11 @@ void IJSVGEndTransactionLock(void);
IJSVGLayer* _layerTree;
CGRect _viewBox;
CGSize _proposedViewSize;
CGFloat _backingScaleFactor;
CGFloat _lastProposedBackingScale;
IJSVGRenderQuality _lastProposedRenderQuality;
CGFloat _backingScale;
NSMutableDictionary* _replacementColors;
IJSVGQuartzRenderer* _quartzRenderer;
struct {
unsigned int shouldHandleForeignObject : 1;
@@ -90,9 +87,6 @@ void IJSVGEndTransactionLock(void);
+ (id)svgNamed:(NSString*)string;
+ (id)svgNamed:(NSString*)string
delegate:(id<IJSVGDelegate>)delegate;
+ (id)svgNamed:(NSString*)string
useCache:(BOOL)useCache
delegate:(id<IJSVGDelegate>)delegate;
- (id)initWithImage:(NSImage*)image;
@@ -107,8 +101,6 @@ void IJSVGEndTransactionLock(void);
- (id)initWithSVGString:(NSString*)string
error:(NSError**)error;
- (id)initWithFile:(NSString*)file
useCache:(BOOL)useCache;
- (id)initWithFile:(NSString*)file;
- (id)initWithFile:(NSString*)file
error:(NSError**)error;
@@ -117,19 +109,12 @@ void IJSVGEndTransactionLock(void);
- (id)initWithFile:(NSString*)file
error:(NSError**)error
delegate:(id<IJSVGDelegate>)delegate;
- (id)initWithFile:(NSString*)file
useCache:(BOOL)useCache
error:(NSError**)error
delegate:(id<IJSVGDelegate>)delegate;
- (id)initWithFilePathURL:(NSURL*)aURL;
- (id)initWithFilePathURL:(NSURL*)aURL
useCache:(BOOL)useCache;
- (id)initWithFilePathURL:(NSURL*)aURL
error:(NSError**)error;
- (id)initWithFilePathURL:(NSURL*)aURL
delegate:(id<IJSVGDelegate>)delegate;
- (id)initWithFilePathURL:(NSURL*)aURL
useCache:(BOOL)useCache
error:(NSError**)error
delegate:(id<IJSVGDelegate>)delegate;
- (NSImage*)imageWithSize:(NSSize)aSize;
@@ -140,6 +125,10 @@ void IJSVGEndTransactionLock(void);
- (NSImage*)imageByMaintainingAspectRatioWithSize:(NSSize)aSize
flipped:(BOOL)flipped
error:(NSError**)error;
- (CGImageRef)newCGImageRefWithSize:(CGSize)size
flipped:(BOOL)flipped
error:(NSError**)error;
- (BOOL)drawAtPoint:(NSPoint)point
size:(NSSize)size;
- (BOOL)drawAtPoint:(NSPoint)point
@@ -7,7 +7,6 @@
//
#import "IJSVG.h"
#import "IJSVGCache.h"
#import "IJSVGExporter.h"
#import "IJSVGTransaction.h"
@@ -20,52 +19,41 @@
- (void)dealloc
{
IJSVGBeginTransactionLock();
// this can all be called on the background thread to be released
(void)([renderingBackingScaleHelper release]),
renderingBackingScaleHelper = nil;
(void)([_group release]), _group = nil;
(void)([_layerTree release]), _layerTree = nil;
(void)([_replacementColors release]), _replacementColors = nil;
(void)([_quartzRenderer release]), _quartzRenderer = nil;
(void)([_style release]), _style = nil;
(void)([_group release]), _group = nil;
// kill any memory that has been around
(void)([_layerTree release]), _layerTree = nil;
[super dealloc];
IJSVGEndTransactionLock();
}
+ (id)svgNamed:(NSString*)string error:(NSError**)error
{
return [self.class svgNamed:string error:error delegate:nil];
}
+ (id)svgNamed:(NSString*)string
{
return [self.class svgNamed:string error:nil];
}
+ (id)svgNamed:(NSString*)string
useCache:(BOOL)useCache
delegate:(id<IJSVGDelegate>)delegate
{
return [self.class svgNamed:string
useCache:useCache
error:nil
delegate:delegate];
}
+ (id)svgNamed:(NSString*)string delegate:(id<IJSVGDelegate>)delegate
{
return [self.class svgNamed:string error:nil delegate:delegate];
}
+ (id)svgNamed:(NSString*)string
error:(NSError**)error
delegate:(id<IJSVGDelegate>)delegate
{
return [self svgNamed:string useCache:YES error:error delegate:delegate];
return [self.class svgNamed:string
error:error
delegate:nil];
}
+ (id)svgNamed:(NSString*)string
{
return [self.class svgNamed:string
error:nil];
}
+ (id)svgNamed:(NSString*)string
delegate:(id<IJSVGDelegate>)delegate
{
return [self.class svgNamed:string
error:nil
delegate:delegate];
}
+ (id)svgNamed:(NSString*)string
useCache:(BOOL)useCache
error:(NSError**)error
delegate:(id<IJSVGDelegate>)delegate
{
@@ -79,7 +67,6 @@
ofType:ext])
!= nil) {
return [[[self alloc] initWithFile:str
useCache:useCache
error:error
delegate:delegate] autorelease];
}
@@ -91,20 +78,19 @@
__block IJSVGGroupLayer* layer = nil;
__block IJSVGImageLayer* imageLayer = nil;
// make sure we obtain a lock, with whatever we do with layers!
IJSVGBeginTransactionLock();
// create the layers we require
layer = [[[IJSVGGroupLayer alloc] init] autorelease];
imageLayer =
[[[IJSVGImageLayer alloc] initWithImage:image] autorelease];
[layer addSublayer:imageLayer];
IJSVGEndTransactionLock();
// return the initialized SVG
return [self initWithSVGLayer:layer viewBox:imageLayer.frame];
return [self initWithSVGLayer:layer
viewBox:imageLayer.frame];
}
- (id)initWithSVGLayer:(IJSVGGroupLayer*)group viewBox:(NSRect)viewBox
- (id)initWithSVGLayer:(IJSVGGroupLayer*)group
viewBox:(NSRect)viewBox
{
// this completely bypasses passing of files
if ((self = [super init]) != nil) {
@@ -120,33 +106,9 @@
- (id)initWithFile:(NSString*)file
{
return [self initWithFile:file delegate:nil];
}
- (id)initWithFile:(NSString*)file useCache:(BOOL)useCache
{
return [self initWithFile:file useCache:useCache error:nil delegate:nil];
}
- (id)initWithFile:(NSString*)file
useCache:(BOOL)useCache
error:(NSError**)error
delegate:(id<IJSVGDelegate>)delegate
{
return [self initWithFilePathURL:[NSURL fileURLWithPath:file]
useCache:useCache
error:error
delegate:delegate];
}
- (id)initWithFile:(NSString*)file error:(NSError**)error
{
return [self initWithFile:file error:error delegate:nil];
}
- (id)initWithFile:(NSString*)file delegate:(id<IJSVGDelegate>)delegate
{
return [self initWithFile:file error:nil delegate:delegate];
return [self initWithFile:file
error:nil
delegate:nil];
}
- (id)initWithFile:(NSString*)file
@@ -154,56 +116,53 @@
delegate:(id<IJSVGDelegate>)delegate
{
return [self initWithFilePathURL:[NSURL fileURLWithPath:file]
useCache:YES
error:error
delegate:delegate];
}
- (id)initWithFilePathURL:(NSURL*)aURL
- (id)initWithFile:(NSString*)file
error:(NSError**)error
{
return [self initWithFilePathURL:aURL useCache:YES error:nil delegate:nil];
return [self initWithFile:file
error:error
delegate:nil];
}
- (id)initWithFilePathURL:(NSURL*)aURL error:(NSError**)error
- (id)initWithFile:(NSString*)file
delegate:(id<IJSVGDelegate>)delegate
{
return [self initWithFilePathURL:aURL useCache:YES error:error delegate:nil];
}
- (id)initWithFilePathURL:(NSURL*)aURL useCache:(BOOL)useCache
{
return
[self initWithFilePathURL:aURL
useCache:useCache
error:nil
delegate:nil];
}
- (id)initWithFilePathURL:(NSURL*)aURL delegate:(id<IJSVGDelegate>)delegate
{
return
[self initWithFilePathURL:aURL
useCache:YES
error:nil
delegate:delegate];
return [self initWithFile:file
error:nil
delegate:delegate];
}
- (id)initWithFilePathURL:(NSURL*)aURL
{
return [self initWithFilePathURL:aURL
error:nil
delegate:nil];
}
- (id)initWithFilePathURL:(NSURL*)aURL
error:(NSError**)error
{
return [self initWithFilePathURL:aURL
error:error
delegate:nil];
}
- (id)initWithFilePathURL:(NSURL*)aURL
delegate:(id<IJSVGDelegate>)delegate
{
return [self initWithFilePathURL:aURL
error:nil
delegate:delegate];
}
- (id)initWithFilePathURL:(NSURL*)aURL
useCache:(BOOL)useCache
error:(NSError**)error
delegate:(id<IJSVGDelegate>)delegate
{
#ifndef __clang_analyzer__
// check the cache first
if (useCache && [IJSVGCache enabled]) {
IJSVG* svg = nil;
if ((svg = [IJSVGCache cachedSVGForFileURL:aURL]) != nil) {
// have to release, as this was called from an alloc..!
[self release];
return [svg retain];
}
}
// create the object
if ((self = [super init]) != nil) {
NSError* anError = nil;
@@ -214,8 +173,9 @@
[self _checkDelegate];
// create the group
_group = [[IJSVGParser groupForFileURL:aURL error:&anError delegate:self]
retain];
_group = [[IJSVGParser groupForFileURL:aURL
error:&anError
delegate:self] retain];
[self _setupBasicInfoFromGroup];
[self _setupBasicsFromAnyInitializer];
@@ -228,24 +188,23 @@
(void)([self release]), self = nil;
return nil;
}
// cache the file
if (useCache && [IJSVGCache enabled]) {
[IJSVGCache cacheSVG:self fileURL:aURL];
}
}
#endif
return self;
}
- (id)initWithSVGString:(NSString*)string
{
return [self initWithSVGString:string error:nil delegate:nil];
return [self initWithSVGString:string
error:nil
delegate:nil];
}
- (id)initWithSVGString:(NSString*)string error:(NSError**)error
- (id)initWithSVGString:(NSString*)string
error:(NSError**)error
{
return [self initWithSVGString:string error:error delegate:nil];
return [self initWithSVGString:string
error:error
delegate:nil];
}
- (id)initWithSVGString:(NSString*)string
@@ -300,7 +259,7 @@
{
self.style = [[[IJSVGRenderingStyle alloc] init] autorelease];
self.clipToViewport = YES;
self.renderQuality = IJSVGRenderQualityFullResolution;
self.renderQuality = kIJSVGRenderQualityFullResolution;
// setup low level backing scale
_lastProposedBackingScale = 0.f;
@@ -360,17 +319,25 @@
- (NSImage*)imageWithSize:(NSSize)aSize
{
return [self imageWithSize:aSize flipped:NO error:nil];
return [self imageWithSize:aSize
flipped:NO
error:nil];
}
- (NSImage*)imageWithSize:(NSSize)aSize error:(NSError**)error;
- (NSImage*)imageWithSize:(NSSize)aSize
error:(NSError**)error;
{
return [self imageWithSize:aSize flipped:NO error:error];
return [self imageWithSize:aSize
flipped:NO
error:error];
}
- (NSImage*)imageWithSize:(NSSize)aSize flipped:(BOOL)flipped
- (NSImage*)imageWithSize:(NSSize)aSize
flipped:(BOOL)flipped
{
return [self imageWithSize:aSize flipped:flipped error:nil];
return [self imageWithSize:aSize
flipped:flipped
error:nil];
}
- (NSRect)computeOriginalDrawingFrameWithSize:(NSSize)aSize
@@ -380,22 +347,63 @@
_proposedViewSize.height * _clipScale);
}
- (CGImageRef)newCGImageRefWithSize:(CGSize)size
flipped:(BOOL)flipped
error:(NSError**)error
{
// setup the drawing rect, this is used for both the intial drawing
// and the backing scale helper block
NSRect rect = (CGRect){
.origin = CGPointZero,
.size = (CGSize)size
};
// this is highly important this is setup
[self _beginDraw:rect];
// make sure we setup the scale based on the backing scale factor
CGFloat scale = [self backindScaleFactor:NULL];
// create the context and colorspace
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef ref = CGBitmapContextCreate(NULL, (int)size.width * scale,
(int)size.height * scale, 8, 0, colorSpace,
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
// scale the context
CGContextScaleCTM(ref, scale, scale);
if (flipped == YES) {
CGContextTranslateCTM(ref, 0.f, size.height);
CGContextScaleCTM(ref, 1.f, -1.f);
}
// draw the SVG into the context
[self _drawInRect:rect
context:ref
error:error];
// create the image from the context
CGImageRef imageRef = CGBitmapContextCreateImage(ref);
// release all things!
CGColorSpaceRelease(colorSpace);
CGContextRelease(ref);
return imageRef;
}
- (NSImage*)imageWithSize:(NSSize)aSize
flipped:(BOOL)flipped
error:(NSError**)error
{
NSImage* im = [[[NSImage alloc] initWithSize:aSize] autorelease];
[im lockFocus];
CGContextRef ref = [[NSGraphicsContext currentContext] CGContext];
CGContextSaveGState(ref);
if (flipped) {
CGContextTranslateCTM(ref, 0.f, aSize.height);
CGContextScaleCTM(ref, 1.f, -1.f);
}
[self drawAtPoint:NSMakePoint(0.f, 0.f) size:aSize error:error];
CGContextRestoreGState(ref);
[im unlockFocus];
return im;
CGImageRef ref = [self newCGImageRefWithSize:aSize
flipped:flipped
error:error];
NSImage* image = [[NSImage alloc] initWithCGImage:ref
size:aSize];
CGImageRelease(ref);
return image.autorelease;
}
- (NSImage*)imageByMaintainingAspectRatioWithSize:(NSSize)aSize
@@ -423,7 +431,8 @@
return [self PDFDataWithRect:rect error:nil];
}
- (NSData*)PDFDataWithRect:(NSRect)rect error:(NSError**)error
- (NSData*)PDFDataWithRect:(NSRect)rect
error:(NSError**)error
{
// create the data for the PDF
NSMutableData* data = [[[NSMutableData alloc] init] autorelease];
@@ -444,10 +453,8 @@
// make sure we set the masks to path bits n bobs
[self _beginVectorDraw];
{
// draw the icon
[self _drawInRect:(NSRect)box context:context error:error];
}
// draw the icon
[self _drawInRect:(NSRect)box context:context error:error];
[self _endVectorDraw];
CGContextEndPage(context);
@@ -507,15 +514,21 @@
};
}
- (BOOL)drawAtPoint:(NSPoint)point size:(NSSize)aSize
- (BOOL)drawAtPoint:(NSPoint)point
size:(NSSize)aSize
{
return [self drawAtPoint:point size:aSize error:nil];
return [self drawAtPoint:point
size:aSize
error:nil];
}
- (BOOL)drawAtPoint:(NSPoint)point size:(NSSize)aSize error:(NSError**)error
- (BOOL)drawAtPoint:(NSPoint)point
size:(NSSize)aSize
error:(NSError**)error
{
return
[self drawInRect:NSMakeRect(point.x, point.y, aSize.width, aSize.height)
[self drawInRect:NSMakeRect(point.x, point.y,
aSize.width, aSize.height)
error:error];
}
@@ -524,7 +537,8 @@
return [self drawInRect:rect error:nil];
}
- (BOOL)drawInRect:(NSRect)rect error:(NSError**)error
- (BOOL)drawInRect:(NSRect)rect
error:(NSError**)error
{
return [self _drawInRect:rect
context:[[NSGraphicsContext currentContext] CGContext]
@@ -537,7 +551,8 @@
return (CGFloat)(_scale + actualScale);
}
- (NSRect)computeRectDrawingInRect:(NSRect)rect isValid:(BOOL*)valid
- (NSRect)computeRectDrawingInRect:(NSRect)rect
isValid:(BOOL*)valid
{
// we also need to calculate the viewport so we can clip
// the drawing if needed
@@ -558,7 +573,8 @@
return viewPort;
}
- (void)drawInRect:(NSRect)rect context:(CGContextRef)context
- (void)drawInRect:(NSRect)rect
context:(CGContextRef)context
{
[self _drawInRect:rect context:context error:nil];
}
@@ -568,83 +584,78 @@
error:(NSError**)error
{
// prep for draw...
@synchronized(self)
{
CGContextSaveGState(ref);
@try {
[self _beginDraw:rect];
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);
// render the layer, its really important we lock
// the transaction when drawing
IJSVGBeginTransactionLock();
// do we need to update the backing scales on the
// layers?
if (self.renderingBackingScaleHelper != nil) {
[self _askHelperForBackingScale];
}
CGInterpolationQuality quality;
switch (self.renderQuality) {
case IJSVGRenderQualityLow: {
quality = kCGInterpolationLow;
break;
}
case IJSVGRenderQualityOptimized: {
quality = kCGInterpolationMedium;
break;
}
default: {
quality = kCGInterpolationHigh;
}
}
CGContextSetInterpolationQuality(ref, quality);
[self.layer renderInContext:ref];
IJSVGEndTransactionLock();
}
} @catch (NSException* exception) {
// just catch and give back a drawing error to the caller
// 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?
if (self.renderingBackingScaleHelper != nil) {
[self backindScaleFactor:nil];
}
CGInterpolationQuality quality;
switch (self.renderQuality) {
case kIJSVGRenderQualityLow: {
quality = kCGInterpolationLow;
break;
}
case kIJSVGRenderQualityOptimized: {
quality = kCGInterpolationMedium;
break;
}
default: {
quality = kCGInterpolationHigh;
}
}
CGContextSetInterpolationQuality(ref, quality);
[self.layer renderInContext:ref];
}
} @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);
}
- (void)_askHelperForBackingScale
- (CGFloat)backindScaleFactor:(CGFloat* _Nullable)proposedBackingScale
{
CGFloat scale = (self.renderingBackingScaleHelper)();
__block CGFloat scale = 1.f;
scale = (self.renderingBackingScaleHelper)();
if (scale < 1.f) {
scale = 1.f;
}
_backingScaleFactor = scale;
// make sure we multiple the scale by the scale of the rendered clip
// or it will be blurry for gradients and other bitmap drawing
@@ -653,12 +664,15 @@
// dont do anything, nothing has changed, no point of iterating over
// every layer for no reason!
if (scale == _lastProposedBackingScale && renderQuality == _lastProposedRenderQuality) {
return;
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) = ^void(CALayer* layer, BOOL isMask) {
@@ -671,6 +685,7 @@
// gogogo
[IJSVGLayer recursivelyWalkLayer:self.layer withBlock:block];
return _backingScaleFactor;
}
- (IJSVGLayer*)layerWithTree:(IJSVGLayerTree*)tree
@@ -681,9 +696,7 @@
}
// force rebuild of the tree
IJSVGBeginTransactionLock();
_layerTree = [[tree layerForNode:_group] retain];
IJSVGEndTransactionLock();
return _layerTree;
}
@@ -818,7 +831,9 @@
withSVGString:(NSString*)string
{
if (_delegate != nil && _respondsTo.shouldHandleSubSVG == 1) {
[_delegate svg:self foundSubSVG:subSVG withSVGString:string];
[_delegate svg:self
foundSubSVG:subSVG
withSVGString:string];
}
}
@@ -826,7 +841,8 @@
shouldHandleForeignObject:(IJSVGForeignObject*)foreignObject
{
if (_delegate != nil && _respondsTo.shouldHandleForeignObject == 1) {
return [_delegate svg:self shouldHandleForeignObject:foreignObject];
return [_delegate svg:self
shouldHandleForeignObject:foreignObject];
}
return NO;
}
@@ -836,7 +852,9 @@
document:(NSXMLDocument*)document
{
if (_delegate != nil && _respondsTo.handleForeignObject == 1) {
[_delegate svg:self handleForeignObject:foreignObject document:document];
[_delegate svg:self
handleForeignObject:foreignObject
document:document];
}
}
@@ -104,7 +104,7 @@
+ (IJSVG*)convertIJSVGPathToSVG:(IJSVGPath*)path
{
CGPathRef cgPath = [IJSVGUtils newCGPathFromBezierPath:path.path];
CGPathRef cgPath = [path.path newCGPathRef:NO];
CGPathRef flippedPath = [IJSVGUtils newFlippedCGPath:cgPath];
IJSVG* svg = [self convertPathToSVG:flippedPath];
CGPathRelease(flippedPath);
@@ -115,7 +115,6 @@
+ (IJSVG*)convertPathToSVG:(CGPathRef)path
{
__block IJSVG* svg = nil;
IJSVGBeginTransactionLock();
IJSVGGroupLayer* layer = [[[IJSVGGroupLayer alloc] init] autorelease];
IJSVGShapeLayer* shape = [[[IJSVGShapeLayer alloc] init] autorelease];
[layer addSublayer:shape];
@@ -123,7 +122,6 @@
CGRect box = CGPathGetPathBoundingBox(path);
svg = [[IJSVG alloc] initWithSVGLayer:layer
viewBox:box];
IJSVGEndTransactionLock();
return [svg autorelease];
}
@@ -11,6 +11,7 @@
@class IJSVG;
typedef void (^IJSVGCGPathHandler)(const CGPathElement* pathElement);
typedef void (^IJSVGPathElementEnumerationBlock)(const CGPathElement* pathElement, CGPoint currentPoint);
void IJSVGExporterPathCaller(void* info, const CGPathElement* pathElement);
@@ -31,10 +32,13 @@ typedef NS_OPTIONS(NSInteger, IJSVGExporterOptions) {
IJSVGExporterOptionRemoveWidthHeightAttributes = 1 << 13,
IJSVGExporterOptionColorAllowRRGGBBAA = 1 << 14,
IJSVGExporterOptionRemoveComments = 1 << 15,
IJSVGExporterOptionAll = IJSVGExporterOptionRemoveUselessDef | IJSVGExporterOptionRemoveUselessGroups | IJSVGExporterOptionCreateUseForPaths | IJSVGExporterOptionMoveAttributesToGroup | IJSVGExporterOptionSortAttributes | IJSVGExporterOptionCollapseGroups | IJSVGExporterOptionCleanupPaths | IJSVGExporterOptionRemoveHiddenElements | IJSVGExporterOptionScaleToSizeIfNecessary | IJSVGExporterOptionCompressOutput | IJSVGExporterOptionCollapseGradients | IJSVGExporterOptionRemoveWidthHeightAttributes | IJSVGExporterOptionColorAllowRRGGBBAA | IJSVGExporterOptionRemoveComments
IJSVGExporterOptionCenterWithinViewBox = 1 << 16,
IJSVGExporterOptionAll = IJSVGExporterOptionRemoveUselessDef | IJSVGExporterOptionRemoveUselessGroups | IJSVGExporterOptionCreateUseForPaths | IJSVGExporterOptionMoveAttributesToGroup | IJSVGExporterOptionSortAttributes | IJSVGExporterOptionCollapseGroups | IJSVGExporterOptionCleanupPaths | IJSVGExporterOptionRemoveHiddenElements | IJSVGExporterOptionScaleToSizeIfNecessary | IJSVGExporterOptionCompressOutput | IJSVGExporterOptionCollapseGradients | IJSVGExporterOptionRemoveWidthHeightAttributes | IJSVGExporterOptionColorAllowRRGGBBAA | IJSVGExporterOptionRemoveComments | IJSVGExporterOptionCenterWithinViewBox
};
BOOL IJSVGExporterHasOption(IJSVGExporterOptions options, NSInteger option);
void IJSVGEnumerateCGPathElements(CGPathRef path, IJSVGPathElementEnumerationBlock enumBlock);
const NSArray* IJSVGShortCharacterArray(void);
@interface IJSVGExporter : NSObject {
@@ -44,7 +48,6 @@ BOOL IJSVGExporterHasOption(IJSVGExporterOptions options, NSInteger option);
IJSVGExporterOptions _options;
NSXMLDocument* _dom;
NSXMLElement* _defElement;
NSXMLElement* _scaledRootNode;
NSInteger _idCount;
NSInteger _shortIdCount;
}
@@ -36,7 +36,7 @@ BOOL IJSVGExporterHasOption(IJSVGExporterOptions options, NSInteger option)
return (options & option) != 0;
};
const NSArray* IJSVGShortCharacterArray()
const NSArray* IJSVGShortCharacterArray(void)
{
static NSArray* _array;
static dispatch_once_t onceToken;
@@ -130,7 +130,6 @@ NSString* IJSVGHash(NSString* key)
- (void)dealloc
{
(void)([_scaledRootNode release]), _scaledRootNode = nil;
(void)([_svg release]), _svg = nil;
(void)([_dom release]), _dom = nil;
(void)([_defElement release]), _defElement = nil;
@@ -175,7 +174,7 @@ NSString* IJSVGHash(NSString* key)
return viewBox;
}
- (NSXMLElement*)rootNode
- (NSXMLElement*)rootNode:(NSXMLElement**)nestedRoot
{
// generates the root document
NSXMLElement* root = [[[NSXMLElement alloc] initWithName:@"svg"] autorelease];
@@ -190,7 +189,7 @@ NSString* IJSVGHash(NSString* key)
};
// add on width and height unless specified otherwise
if ((_options & IJSVGExporterOptionRemoveWidthHeightAttributes) == 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionRemoveWidthHeightAttributes) == NO) {
NSMutableDictionary* attDict = [[attributes mutableCopy] autorelease];
attDict[@"width"] = IJSVGShortFloatString(_size.width);
attDict[@"height"] = IJSVGShortFloatString(_size.height);
@@ -198,39 +197,44 @@ NSString* IJSVGHash(NSString* key)
}
// was there a size set?
CGFloat scale = 1.f;
NSMutableArray<IJSVGTransform*>* transforms = [[[NSMutableArray alloc] initWithCapacity:2] autorelease];
if (CGSizeEqualToSize(CGSizeZero, _size) == NO && (_size.width != viewBox.size.width && _size.height != viewBox.size.height)) {
// copy the attributes
NSMutableDictionary* att = [[attributes mutableCopy] autorelease];
att[@"width"] = IJSVGShortFloatString(_size.width);
att[@"height"] = IJSVGShortFloatString(_size.height);
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionRemoveWidthHeightAttributes) == NO) {
att[@"width"] = IJSVGShortFloatString(_size.width);
att[@"height"] = IJSVGShortFloatString(_size.height);
}
// scale the whole SVG to fit the specified size
if ((_options & IJSVGExporterOptionScaleToSizeIfNecessary) != 0) {
// work out the scale
CGFloat scale = MIN(_size.width / viewBox.size.width,
_size.height / viewBox.size.height);
// work out the scale
const CGFloat _proposedScale = MIN(_size.width / viewBox.size.width,
_size.height / viewBox.size.height);
// actually do the scale
if (scale != 1.f) {
NSString* scaleString = [NSString stringWithFormat:@"scale(%g)", scale];
NSDictionary* transform = @{ @"transform" : scaleString };
// actually do the scale
if (_proposedScale != 1.f) {
// compute x and y, don't multiply 0
const CGFloat x = viewBox.origin.x == 0.f ? 0.f : (viewBox.origin.x * _proposedScale);
const CGFloat y = viewBox.origin.y == 0.f ? 0.f : (viewBox.origin.y * _proposedScale);
// create the main group and apply transform
_scaledRootNode = [[NSXMLElement alloc] initWithName:@"g"];
IJSVGApplyAttributesToElement(transform, _scaledRootNode);
// reset the viewbox for the exported SVG
NSRect newViewBox = (NSRect){
.origin = NSMakePoint(x, y),
.size = NSMakeSize(_size.width,
_size.height)
};
att[@"viewBox"] = [self viewBoxWithRect:newViewBox];
// add it back onto root
[root addChild:_scaledRootNode];
// do we need to scale?
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionScaleToSizeIfNecessary) == YES) {
IJSVGTransform* transform = nil;
transform = [IJSVGTransform transformByScaleX:_proposedScale
y:_proposedScale];
[transforms addObject:transform];
// compute x and y, dont multiply 0
const CGFloat x = viewBox.origin.x == 0.f ? 0.f : (viewBox.origin.x * scale);
const CGFloat y = viewBox.origin.y == 0.f ? 0.f : (viewBox.origin.y * scale);
// reset the viewbox for the exported SVG
att[@"viewBox"] = [self viewBoxWithRect:(NSRect){
.origin = NSMakePoint(x, y),
.size = NSMakeSize(_size.width, _size.height) }];
// reset the scale
scale = _proposedScale;
}
}
@@ -238,8 +242,39 @@ NSString* IJSVGHash(NSString* key)
attributes = [[att copy] autorelease];
}
// do we need to center the svg within the box?
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionCenterWithinViewBox) == YES) {
CGPoint transformPoint = CGPointMake(_size.width / 2.f - ((viewBox.size.width * scale) / 2.f),
_size.height / 2.f - ((viewBox.size.height * scale) / 2.f));
// work out what transform point we need to do, if any
if (CGPointEqualToPoint(transformPoint, CGPointZero) == NO) {
IJSVGTransform* transform = nil;
transform = [IJSVGTransform transformByTranslatingX:transformPoint.x
y:transformPoint.y];
[transforms addObject:transform];
}
}
// any transform for the root node?
if (transforms.count != 0) {
// concat the transform
CGAffineTransform afTransform = IJSVGConcatTransforms(transforms);
NSXMLElement* transformedElement = [[[NSXMLElement alloc] initWithName:@"g"] autorelease];
NSString* transString = nil;
transString = IJSVGTransformAttributeString(afTransform);
IJSVGApplyAttributesToElement(
@{ @"transform" : transString },
transformedElement);
*nestedRoot = transformedElement;
[root addChild:transformedElement];
}
// apply the attributes
IJSVGApplyAttributesToElement(attributes, root);
if (*nestedRoot == nil) {
*nestedRoot = root;
}
return root;
}
@@ -259,15 +294,15 @@ NSString* IJSVGHash(NSString* key)
- (void)_prepare
{
// create the stand alone DOM
_dom = [[NSXMLDocument alloc] initWithRootElement:[self rootNode]];
NSXMLElement* nestedRoot = nil;
NSXMLElement* rootNode = [self rootNode:&nestedRoot];
_dom = [[NSXMLDocument alloc] initWithRootElement:rootNode];
_dom.version = XML_DOCTYPE_VERSION;
_dom.characterEncoding = XML_DOC_CHARSET;
// sort out header
// sort out stuff, so here we go...
[self _recursiveParseFromLayer:_svg.layer
intoElement:(_scaledRootNode ?: _dom.rootElement)];
intoElement:nestedRoot];
// this needs to be added incase it needs to be cleaned
NSXMLElement* defNode = [self defElement];
@@ -286,7 +321,7 @@ NSString* IJSVGHash(NSString* key)
}
// add generator
if ((_options & IJSVGExporterOptionRemoveComments) == 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionRemoveComments) == NO) {
NSXMLNode* generatorNode = [[[NSXMLNode alloc] initWithKind:NSXMLCommentKind] autorelease];
generatorNode.stringValue = XML_DOC_GENERATOR;
[_dom.rootElement insertChild:generatorNode
@@ -297,52 +332,52 @@ NSString* IJSVGHash(NSString* key)
- (void)_cleanup
{
// remove hidden elements
if ((_options & IJSVGExporterOptionRemoveHiddenElements) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionRemoveHiddenElements) == YES) {
[self _removeHiddenElements];
}
// convert any duplicate paths into use
if ((_options & IJSVGExporterOptionCreateUseForPaths) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionCreateUseForPaths) == YES) {
[self _convertUseElements];
}
// cleanup def
if ((_options & IJSVGExporterOptionRemoveUselessDef) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionRemoveUselessDef) == YES) {
[self _cleanDef];
}
// collapse groups
if ((_options & IJSVGExporterOptionCollapseGroups) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionCollapseGroups) == YES) {
[self _collapseGroups];
}
// clean any blank groups
if ((_options & IJSVGExporterOptionRemoveUselessGroups) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionRemoveUselessGroups) == YES) {
[self _cleanEmptyGroups];
}
// sort attributes
if ((_options & IJSVGExporterOptionSortAttributes) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionSortAttributes) == YES) {
[self _sortAttributesOnElement:_dom.rootElement];
}
// compress groups together
if ((_options & IJSVGExporterOptionCollapseGroups) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionCollapseGroups) == YES) {
[self _compressGroups];
}
// collapse gradients?
if ((_options & IJSVGExporterOptionCollapseGradients) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionCollapseGradients) == YES) {
[self _collapseGradients];
}
// create classes?
if ((_options & IJSVGExporterOptionCreateClasses) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionCreateClasses) == YES) {
[self _createClasses];
}
// move attributes to group
if ((_options & IJSVGExporterOptionMoveAttributesToGroup) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionMoveAttributesToGroup) == YES) {
[self _moveAttributesToGroupWithElement:_dom.rootElement];
}
}
@@ -793,7 +828,7 @@ NSString* IJSVGHash(NSString* key)
}
// append the string
NSString* transformStr = [IJSVGTransform affineTransformToSVGMatrixString:transform];
NSString* transformStr = IJSVGTransformAttributeString(transform);
// apply it to the node
IJSVGApplyAttributesToElement(@{ @"transform" : transformStr }, element);
@@ -961,7 +996,9 @@ NSString* IJSVGHash(NSString* key)
IJSVGColorStringOptions options = IJSVGColorStringOptionForceHEX | IJSVGColorStringOptionAllowShortHand;
NSString* stopColor = [IJSVGColor colorStringFromColor:aColor
options:options];
if ([stopColor isEqualToString:@"#000000"] == NO) {
// dont bother adding default
if ([stopColor isEqualToString:@"#000"] == NO) {
atts[@"stop-color"] = stopColor;
}
@@ -975,7 +1012,6 @@ NSString* IJSVGHash(NSString* key)
}
// att the attributes
IJSVGApplyAttributesToElement(atts, stop);
// append the stop the gradient
@@ -989,7 +1025,7 @@ NSString* IJSVGHash(NSString* key)
NSArray* transforms = layer.gradient.transforms;
if (transforms.count != 0.f) {
CGAffineTransform transform = IJSVGConcatTransforms(transforms);
NSString* transformString = [IJSVGTransform affineTransformToSVGMatrixString:transform];
NSString* transformString = IJSVGTransformAttributeString(transform);
IJSVGApplyAttributesToElement(@{ @"gradientTransform" : transformString }, gradientElement);
}
@@ -1006,15 +1042,6 @@ NSString* IJSVGHash(NSString* key)
}
}
- (CGAffineTransform)affineTransformFromTransforms:(NSArray<IJSVGTransform*>*)transforms
{
CGAffineTransform t = CGAffineTransformIdentity;
for (IJSVGTransform* transform in transforms) {
t = CGAffineTransformConcat(t, [transform CGAffineTransform]);
}
return t;
}
- (NSXMLElement*)elementForImage:(IJSVGImageLayer*)layer
fromParent:(NSXMLElement*)parent
{
@@ -1049,17 +1076,38 @@ NSString* IJSVGHash(NSString* key)
- (IJSVGColorStringOptions)colorOptions
{
IJSVGColorStringOptions options = IJSVGColorStringOptionDefault;
if ((_options & IJSVGExporterOptionColorAllowRRGGBBAA) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionColorAllowRRGGBBAA) == YES) {
options |= IJSVGColorStringOptionAllowRRGGBBAA;
}
return options;
}
- (NSString*)elementNameForPrimitiveType:(IJSVGPrimitivePathType)primitiveType
{
switch (primitiveType) {
case kIJSVGPrimitivePathTypeRect:
return @"rect";
case kIJSVGPrimitivePathTypePolyLine:
return @"polyline";
case kIJSVGPrimitivePathTypeEllipse:
return @"ellipse";
case kIJSVGPrimitivePathTypeCircle:
return @"circle";
case kIJSVGPrimitivePathTypeLine:
return @"line";
case kIJSVGPrimitivePathTypePolygon:
return @"polygon";
case kIJSVGPrimitivePathTypePath:
default:
return @"path";
}
}
- (NSXMLElement*)elementForShape:(IJSVGShapeLayer*)layer
fromParent:(NSXMLElement*)parent
{
NSXMLElement* e = [[[NSXMLElement alloc] init] autorelease];
e.name = @"path";
e.name = [self elementNameForPrimitiveType:layer.primitiveType];
CGPathRef path = layer.path;
// copy the path as we want to translate
@@ -1070,7 +1118,94 @@ NSString* IJSVGHash(NSString* key)
NSMutableDictionary* dict = [[[NSMutableDictionary alloc] init] autorelease];
// path
dict[@"d"] = [self pathFromCGPath:transformPath];
switch (layer.primitiveType) {
case kIJSVGPrimitivePathTypeRect: {
__block BOOL radiusSet = NO;
IJSVGEnumerateCGPathElements(transformPath, ^(const CGPathElement* pathElement, CGPoint currentPoint) {
if (radiusSet == NO && pathElement->type == kCGPathElementAddCurveToPoint) {
radiusSet = YES;
CGFloat radX = fabs(pathElement->points[0].x - currentPoint.x);
CGFloat radY = fabs(pathElement->points[0].y - currentPoint.y);
dict[@"rx"] = IJSVGShortFloatString(radX);
if (radX != radY) {
dict[@"ry"] = IJSVGShortFloatString(radY);
}
}
});
CGRect boundingBox = CGPathGetBoundingBox(transformPath);
if (boundingBox.origin.x != 0.f) {
dict[@"x"] = IJSVGShortFloatString(boundingBox.origin.x);
}
if (boundingBox.origin.y != 0.f) {
dict[@"y"] = IJSVGShortFloatString(boundingBox.origin.y);
}
dict[@"width"] = IJSVGShortFloatString(boundingBox.size.width);
dict[@"height"] = IJSVGShortFloatString(boundingBox.size.height);
break;
}
case kIJSVGPrimitivePathTypeLine: {
IJSVGEnumerateCGPathElements(transformPath, ^(const CGPathElement* pathElement, CGPoint currentPoint) {
switch (pathElement->type) {
case kCGPathElementMoveToPoint: {
dict[@"x1"] = IJSVGShortFloatString(pathElement->points[0].x);
dict[@"y1"] = IJSVGShortFloatString(pathElement->points[0].y);
break;
}
case kCGPathElementAddLineToPoint: {
dict[@"x2"] = IJSVGShortFloatString(pathElement->points[0].x);
dict[@"y2"] = IJSVGShortFloatString(pathElement->points[0].y);
break;
}
default:
break;
}
});
break;
}
case kIJSVGPrimitivePathTypePolygon:
case kIJSVGPrimitivePathTypePolyLine: {
NSMutableArray<NSString*>* points = [[[NSMutableArray alloc] init] autorelease];
IJSVGEnumerateCGPathElements(transformPath, ^(const CGPathElement* pathElement, CGPoint currentPoint) {
switch (pathElement->type) {
case kCGPathElementMoveToPoint: {
[points addObject:IJSVGPointToCommandString(pathElement->points[0])];
break;
}
case kCGPathElementAddLineToPoint: {
[points addObject:IJSVGPointToCommandString(pathElement->points[0])];
break;
}
default:
break;
}
});
// polygon does not need the move to command
if (layer.primitiveType == kIJSVGPrimitivePathTypePolygon) {
[points removeLastObject];
}
dict[@"points"] = [points componentsJoinedByString:@" "];
break;
}
case kIJSVGPrimitivePathTypeEllipse: {
CGRect boundingBox = CGPathGetPathBoundingBox(transformPath);
dict[@"cx"] = IJSVGShortFloatString(boundingBox.origin.x + boundingBox.size.width / 2.f);
dict[@"cy"] = IJSVGShortFloatString(boundingBox.origin.y + boundingBox.size.height / 2.f);
dict[@"rx"] = IJSVGShortFloatString(boundingBox.size.width / 2.f);
dict[@"ry"] = IJSVGShortFloatString(boundingBox.size.height / 2.f);
break;
}
case kIJSVGPrimitivePathTypeCircle: {
// IJSVGCGPathHandler callback = ^(const CGPathElement * pathElement) {
CGRect boundingBox = CGPathGetPathBoundingBox(transformPath);
dict[@"cx"] = IJSVGShortFloatString(boundingBox.origin.x + boundingBox.size.width / 2.f);
dict[@"cy"] = IJSVGShortFloatString(boundingBox.origin.y + boundingBox.size.height / 2.f);
dict[@"r"] = IJSVGShortFloatString(boundingBox.size.width / 2.f);
break;
}
case kIJSVGPrimitivePathTypePath:
default:
dict[@"d"] = [self pathFromCGPath:transformPath];
}
CGPathRelease(transformPath);
@@ -1277,7 +1412,7 @@ NSString* IJSVGHash(NSString* key)
- (NSString*)SVGString
{
NSXMLNodeOptions options = NSXMLNodePrettyPrint;
if ((_options & IJSVGExporterOptionCompressOutput) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionCompressOutput) == YES) {
options = NSXMLNodeOptionsNone;
}
return [_dom XMLStringWithOptions:options];
@@ -1296,7 +1431,7 @@ NSString* IJSVGHash(NSString* key)
NSArray* instructions = [IJSVGExporterPathInstruction instructionsFromPath:path];
// work out what to do...
if ((_options & IJSVGExporterOptionCleanupPaths) != 0) {
if (IJSVGExporterHasOption(_options, IJSVGExporterOptionCleanupPaths) == YES) {
[IJSVGExporterPathInstruction convertInstructionsToRelativeCoordinates:instructions];
}
return [IJSVGExporterPathInstruction pathStringFromInstructions:instructions];
@@ -1308,6 +1443,39 @@ void IJSVGExporterPathCaller(void* info, const CGPathElement* pathElement)
handler(pathElement);
};
void IJSVGEnumerateCGPathElements(CGPathRef path, IJSVGPathElementEnumerationBlock enumBlock)
{
__block CGPoint currentPoint = CGPointZero;
CGPathApplyWithBlock(path, ^(const CGPathElement* _Nonnull element) {
switch (element->type) {
case kCGPathElementMoveToPoint: {
enumBlock(element, currentPoint);
currentPoint = element->points[0];
break;
}
case kCGPathElementAddLineToPoint: {
enumBlock(element, currentPoint);
currentPoint = element->points[0];
break;
}
case kCGPathElementAddCurveToPoint: {
enumBlock(element, currentPoint);
currentPoint = element->points[2];
break;
}
case kCGPathElementAddQuadCurveToPoint: {
enumBlock(element, currentPoint);
currentPoint = element->points[1];
break;
}
case kCGPathElementCloseSubpath: {
enumBlock(element, currentPoint);
break;
}
}
});
};
- (void)sortAttributesOnElement:(NSXMLElement*)element
{
const NSArray* order = @[ @"id", @"width", @"height", @"x", @"x1", @"x2",
@@ -8,6 +8,13 @@
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef struct {
char instruction;
NSArray<NSString*>* params;
} IJSVGExporterPathInstructionCommand;
@interface IJSVGExporterPathInstruction : NSObject {
@private
@@ -16,6 +23,9 @@
CGFloat* _data;
}
IJSVGExporterPathInstructionCommand* IJSVGExporterPathInstructionCommandCopy(IJSVGExporterPathInstructionCommand command);
void IJSVGExporterPathInstructionCommandFree(IJSVGExporterPathInstructionCommand* _Nullable command);
+ (NSArray<IJSVGExporterPathInstruction*>*)instructionsFromPath:(CGPathRef)path;
- (id)initWithInstruction:(char)instruction
@@ -28,5 +38,7 @@
+ (void)convertInstructionsToRelativeCoordinates:(NSArray<IJSVGExporterPathInstruction*>*)instructions;
+ (NSString*)pathStringFromInstructions:(NSArray<IJSVGExporterPathInstruction*>*)instructions;
+ (NSString*)pathStringWithInstructionSet:(NSArray<NSValue*>*)instructionSets;
@end
NS_ASSUME_NONNULL_END
@@ -8,6 +8,7 @@
#import "IJSVGExporter.h"
#import "IJSVGExporterPathInstruction.h"
#import "IJSVGUtils.h"
@implementation IJSVGExporterPathInstruction
@@ -53,87 +54,140 @@
return _data;
}
IJSVGExporterPathInstructionCommand* IJSVGExporterPathInstructionCommandCopy(IJSVGExporterPathInstructionCommand command)
{
IJSVGExporterPathInstructionCommand* copy = NULL;
copy = (IJSVGExporterPathInstructionCommand*)malloc(sizeof(IJSVGExporterPathInstructionCommand));
copy->instruction = command.instruction;
copy->params = command.params;
return copy;
}
void IJSVGExporterPathInstructionCommandFree(IJSVGExporterPathInstructionCommand* _Nullable command)
{
if (command != NULL) {
free(command);
}
}
+ (NSString*)pathStringWithInstructionSet:(NSArray<NSValue*>*)instructionSets
{
IJSVGExporterPathInstructionCommand* lastCommand = NULL;
NSMutableString* string = [[[NSMutableString alloc] init] autorelease];
char* lastCommandChars = NULL;
for (NSValue* value in instructionSets) {
// read back the bytes
IJSVGExporterPathInstructionCommand command;
[value getValue:&command];
// add on the instruction character only if there is no current command
// or the last command is not the same as the current command
// if they both are the same, we still need to seperate them via a space
if (lastCommand == nil || (lastCommand != nil && lastCommand->instruction != command.instruction)) {
[string appendFormat:@"%c", command.instruction];
} else {
[string appendString:@" "];
}
NSInteger index = 0;
for (NSString* dataString in command.params) {
const char* chars = dataString.UTF8String;
// work out if the command is signed and or decimal
BOOL isSigned = chars[0] == '-';
BOOL isDecimal = (isSigned == NO && chars[0] == '.') || (isSigned == YES && chars[1] == '.');
// we also need to know if the previous command was a decimal or not
BOOL lastWasDecimal = NO;
if (lastCommandChars != NULL) {
lastWasDecimal = strchr(lastCommandChars, '.') != NULL;
}
// we only need a space if the current command is not signed
// a decimal and the previous command was decimal too
if (index++ == 0 || isSigned || (isDecimal == YES && lastWasDecimal == YES)) {
[string appendString:dataString];
} else {
[string appendFormat:@" %@", dataString];
}
// store last command chars
lastCommandChars = (char*)chars;
}
// store last command
IJSVGExporterPathInstructionCommandFree(lastCommand);
lastCommand = IJSVGExporterPathInstructionCommandCopy(command);
}
IJSVGExporterPathInstructionCommandFree(lastCommand);
return string;
}
+ (NSString*)pathStringFromInstructions:(NSArray<IJSVGExporterPathInstruction*>*)instructions
{
NSMutableArray* pathData = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray* pathInstructions = [[[NSMutableArray alloc] init] autorelease];
for (IJSVGExporterPathInstruction* instruction in instructions) {
CGFloat* data = instruction.data;
NSString* str = nil;
switch (instruction.instruction) {
// move
case 'M':
case 'm': {
char* buffer;
asprintf(&buffer, "%c%g,%g", instruction.instruction, data[0], data[1]);
str = [NSString stringWithCString:buffer
encoding:NSUTF8StringEncoding];
free(buffer);
[pathData addObject:str];
break;
}
// vertical and horizonal line
case 'V':
case 'v':
case 'H':
case 'h': {
char* buffer;
asprintf(&buffer, "%c%g", instruction.instruction, data[0]);
str = [NSString stringWithCString:buffer
encoding:NSUTF8StringEncoding];
free(buffer);
[pathData addObject:str];
break;
}
// line
case 'L':
const char lowerInstruction = tolower(instruction.instruction);
NSArray<NSString*>* set = nil;
switch (lowerInstruction) {
case 'm':
case 'l': {
char* buffer;
asprintf(&buffer, "%c%g,%g", instruction.instruction, data[0], data[1]);
str = [NSString stringWithCString:buffer
encoding:NSUTF8StringEncoding];
free(buffer);
[pathData addObject:str];
set = @[
IJSVGShortFloatString(data[0]),
IJSVGShortFloatString(data[1])
];
break;
}
case 'v':
case 'h': {
set = @[
IJSVGShortFloatString(data[0])
];
break;
}
// curve
case 'C':
case 'c': {
char* buffer;
asprintf(&buffer, "%c%g,%g %g,%g %g,%g", instruction.instruction,
data[0], data[1], data[2], data[3], data[4], data[5]);
str = [NSString stringWithCString:buffer
encoding:NSUTF8StringEncoding];
free(buffer);
[pathData addObject:str];
set = @[
IJSVGShortFloatString(data[0]),
IJSVGShortFloatString(data[1]),
IJSVGShortFloatString(data[2]),
IJSVGShortFloatString(data[3]),
IJSVGShortFloatString(data[4]),
IJSVGShortFloatString(data[5])
];
break;
}
// quadratic curve
case 'Q':
case 'q': {
char* buffer;
asprintf(&buffer, "%c%g,%g %g,%g", instruction.instruction,
data[0], data[1], data[2], data[3]);
str = [NSString stringWithCString:buffer
encoding:NSUTF8StringEncoding];
free(buffer);
[pathData addObject:str];
set = @[
IJSVGShortFloatString(data[0]),
IJSVGShortFloatString(data[1]),
IJSVGShortFloatString(data[2]),
IJSVGShortFloatString(data[3])
];
break;
}
// close path
case 'Z':
case 'z': {
str = [NSString stringWithFormat:@"%c", instruction.instruction];
[pathData addObject:str];
set = @[];
}
}
// wrap into the command and give to the array
IJSVGExporterPathInstructionCommand wrapper;
wrapper.instruction = instruction.instruction;
wrapper.params = set ?: @[];
// encode and store
NSValue* value = [NSValue valueWithBytes:&wrapper
objCType:@encode(IJSVGExporterPathInstructionCommand)];
[pathInstructions addObject:value];
}
return [pathData componentsJoinedByString:@""];
return [self pathStringWithInstructionSet:pathInstructions];
}
+ (void)convertInstructionsToRelativeCoordinates:(NSArray<IJSVGExporterPathInstruction*>*)instructions
@@ -362,7 +416,7 @@
}
}
}
return instructions;
}
@@ -64,11 +64,11 @@
- (void)setBackingScaleFactor:(CGFloat)backingScaleFactor
{
switch (self.renderQuality) {
case IJSVGRenderQualityOptimized: {
case kIJSVGRenderQualityOptimized: {
backingScaleFactor = (backingScaleFactor * .35f);
break;
}
case IJSVGRenderQualityLow: {
case kIJSVGRenderQualityLow: {
backingScaleFactor = (backingScaleFactor * .05f);
break;
}
@@ -25,6 +25,7 @@
- (void)dealloc
{
self.contents = nil;
(void)([_maskingLayer release]), _maskingLayer = nil;
[super dealloc];
}
@@ -61,20 +62,6 @@
}
}
- (void)addSublayer:(CALayer*)layer
{
if ([layer isKindOfClass:[IJSVGLayer class]] == NO &&
[layer isKindOfClass:[IJSVGShapeLayer class]] == NO) {
NSString* r = [NSString stringWithFormat:@"The layer must be an instance of IJSVGLayer, %@ given.",
[layer class]];
NSException* exception = [NSException exceptionWithName:@"IJSVGInvalidSublayerException"
reason:r
userInfo:nil];
@throw exception;
}
[super addSublayer:layer];
}
- (void)setBackingScaleFactor:(CGFloat)newFactor
{
if (self.backingScaleFactor == newFactor) {
@@ -28,6 +28,7 @@
@property (nonatomic, assign) CGPoint absoluteOrigin;
@property (nonatomic, assign) CGPoint originalPathOrigin;
@property (nonatomic, assign) BOOL convertMasksToPaths;
@property (nonatomic, assign) IJSVGPrimitivePathType primitiveType;
- (void)applySublayerMaskToContext:(CGContextRef)context
forSublayer:(IJSVGLayer*)sublayer
@@ -22,27 +22,15 @@
@synthesize convertMasksToPaths;
@synthesize originalPathOrigin;
@synthesize renderQuality;
@synthesize primitiveType;
- (void)dealloc
{
self.contents = nil;
(void)([_maskingLayer release]), _maskingLayer = nil;
[super dealloc];
}
- (void)addSublayer:(CALayer*)layer
{
if ([layer isKindOfClass:[IJSVGLayer class]] == NO &&
[layer isKindOfClass:[IJSVGShapeLayer class]] == NO) {
NSString* r = [NSString stringWithFormat:@"The layer must be an instance of IJSVGLayer, %@ given.",
[layer class]];
NSException* exception = [NSException exceptionWithName:@"IJSVGInvalidSublayerException"
reason:r
userInfo:nil];
@throw exception;
}
[super addSublayer:layer];
}
- (void)setBackingScaleFactor:(CGFloat)newFactor
{
if (self.backingScaleFactor == newFactor) {
@@ -9,12 +9,13 @@
#import "IJSVGNode.h"
#import <Foundation/Foundation.h>
@interface IJSVGDef : IJSVGNode {
@interface IJSVGDef : NSObject {
@private
NSMutableDictionary* _dict;
}
- (void)addDef:(IJSVGNode*)aDef;
- (IJSVGDef*)defForID:(NSString*)anID;
@end
@@ -18,7 +18,7 @@
- (id)init
{
if ((self = [super initWithDef:NO]) != nil) {
if ((self = [super init]) != nil) {
_dict = [[NSMutableDictionary alloc] init];
}
return self;
@@ -29,13 +29,12 @@
if (aDef.identifier == nil) {
return;
}
[_dict setObject:aDef
forKey:aDef.identifier];
_dict[aDef.identifier] = aDef;
}
- (IJSVGDef*)defForID:(NSString*)anID
{
return [_dict objectForKey:anID];
return _dict[anID];
}
@end
@@ -0,0 +1,39 @@
//
// IJSVGPath.h
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGBezierPathAdditions.h"
#import "IJSVGNode.h"
#import <Foundation/Foundation.h>
@class IJSVGGroup;
typedef NS_ENUM(NSInteger, IJSVGPrimitivePathType) {
kIJSVGPrimitivePathTypePath,
kIJSVGPrimitivePathTypeRect,
kIJSVGPrimitivePathTypePolygon,
kIJSVGPrimitivePathTypePolyLine,
kIJSVGPrimitivePathTypeCircle,
kIJSVGPrimitivePathTypeEllipse,
kIJSVGPrimitivePathTypeLine
};
@interface IJSVGPath : IJSVGNode {
NSBezierPath* path;
CGPoint lastControlPoint;
}
@property (nonatomic, assign) IJSVGPrimitivePathType primitiveType;
@property (nonatomic, retain) NSBezierPath* path;
@property (nonatomic, assign) CGPoint lastControlPoint;
@property (nonatomic, readonly) CGPathRef CGPath;
- (void)close;
- (NSPoint)currentPoint;
@end
@@ -0,0 +1,71 @@
//
// IJSVGPath.m
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGGroup.h"
#import "IJSVGPath.h"
@implementation IJSVGPath
@synthesize path = _path;
@synthesize lastControlPoint;
@synthesize CGPath = _CGPath;
@synthesize primitiveType = _primitiveType;
- (void)dealloc
{
if (_CGPath != nil) {
CGPathRelease(_CGPath);
_CGPath = nil;
}
((void)[_path release]), _path = nil;
[super dealloc];
}
- (id)init
{
if ((self = [super init]) != nil) {
_primitiveType = kIJSVGPrimitivePathTypePath;
_path = NSBezierPath.bezierPath.retain;
}
return self;
}
- (id)copyWithZone:(NSZone*)zone
{
IJSVGPath* node = [super copyWithZone:zone];
node.path = [self.path.copy autorelease];
return node;
}
- (NSPoint)currentPoint
{
return _path.currentPoint;
}
- (void)close
{
[_path closePath];
}
- (void)invlidateCGPath
{
if (_CGPath != nil) {
CGPathRelease(_CGPath);
}
_CGPath = nil;
}
- (CGPathRef)CGPath
{
if (_CGPath == nil) {
_CGPath = [_path newCGPathRef:NO];
}
return _CGPath;
}
@end
@@ -0,0 +1,42 @@
//
// IJSVGCommandParser.h
// IJSVG
//
// Created by Curtis Hard on 23/12/2019.
// Copyright © 2019 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#include <xlocale.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, IJSVGPathDataSequence) {
kIJSVGPathDataSequenceTypeFloat,
kIJSVGPathDataSequenceTypeFlag
};
static NSUInteger const IJSVG_STREAM_FLOAT_BLOCK_SIZE = 50;
static NSUInteger const IJSVG_STREAM_CHAR_BLOCK_SIZE = 20;
typedef struct {
CGFloat* floatBuffer;
NSInteger floatCount;
char* charBuffer;
NSInteger charCount;
} IJSVGPathDataStream;
@interface IJSVGCommandParser : NSObject
IJSVGPathDataStream* IJSVGPathDataStreamCreateDefault(void);
IJSVGPathDataStream* IJSVGPathDataStreamCreate(NSUInteger floatCount, NSUInteger charCount);
void IJSVGPathDataStreamRelease(IJSVGPathDataStream* buffer);
IJSVGPathDataSequence* IJSVGPathDataSequenceCreateWithType(IJSVGPathDataSequence type, NSInteger length);
CGFloat* _Nullable IJSVGParsePathDataStreamSequence(const char* commandChars, NSInteger commandCharLength,
IJSVGPathDataStream* dataStream, IJSVGPathDataSequence* _Nullable sequence,
NSInteger commandLength, NSInteger* _Nullable commandsFound);
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,249 @@
//
// IJSVGCommandParser.m
// IJSVG
//
// Created by Curtis Hard on 23/12/2019.
// Copyright © 2019 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandParser.h"
@implementation IJSVGCommandParser
#define VALID_DIGIT(c) ((c ^ '0') <= 9)
IJSVGPathDataSequence* IJSVGPathDataSequenceCreateWithType(IJSVGPathDataSequence type, NSInteger length)
{
size_t size = sizeof(IJSVGPathDataSequence) * length;
IJSVGPathDataSequence* sequence = (IJSVGPathDataSequence*)malloc(size);
memset(sequence, (int)type, size);
return sequence;
};
// Datastreams work by setting up one stream of bits/memory per SVG
// so that each SVG has a reusable memory block to read and parse paths into.
// As its all linear and one SVG per thread, this saves alot of memory allocation
// calls as we simple can just reuse the buffer that already exists - this also
// allows us to specify the default allocation size, so when parsing viewBox we
// can simply allocate (4*sizeof(CGFloat)) instead of the default 50 slots
IJSVGPathDataStream* IJSVGPathDataStreamCreateDefault(void)
{
return IJSVGPathDataStreamCreate(IJSVG_STREAM_FLOAT_BLOCK_SIZE,
IJSVG_STREAM_CHAR_BLOCK_SIZE);
}
IJSVGPathDataStream* IJSVGPathDataStreamCreate(NSUInteger floatCount, NSUInteger charCount)
{
floatCount = floatCount ?: IJSVG_STREAM_FLOAT_BLOCK_SIZE;
charCount = charCount ?: IJSVG_STREAM_CHAR_BLOCK_SIZE;
IJSVGPathDataStream* buffer = (IJSVGPathDataStream*)malloc(sizeof(IJSVGPathDataStream));
buffer->floatBuffer = (CGFloat*)malloc(sizeof(CGFloat) * floatCount);
buffer->floatCount = floatCount;
buffer->charBuffer = (char*)calloc(sizeof(char), charCount);
buffer->charCount = charCount;
return buffer;
}
void IJSVGPathDataStreamRelease(IJSVGPathDataStream* buffer)
{
free(buffer->charBuffer);
free(buffer->floatBuffer);
free(buffer);
};
CGFloat* _Nullable IJSVGParsePathDataStreamSequence(const char* commandChars, NSInteger commandCharLength,
IJSVGPathDataStream* dataStream, IJSVGPathDataSequence* _Nullable sequence,
NSInteger commandLength, NSInteger* _Nullable commandsFound)
{
// if no command length, its completely pointless function,
// so just return null and set commandsFound to 0, if we dont
// we get a arithmetic error later on due to zero
if (commandLength == 0) {
*commandsFound = 0;
return NULL;
}
// default memory size for the float
NSInteger i = 0;
NSInteger counter = 0;
const char* cString = commandChars;
const char* validChars = "+-.";
// this is much faster then doing strlen as it doesnt need
// to compute the length
NSInteger sLength = commandCharLength;
NSInteger sLengthMinusOne = sLength - 1;
bool isDecimal = false;
int bufferCount = 0;
while (i < sLength) {
char currentChar = *cString++;
// work out next char
char nextChar = (char)0;
if (i < sLengthMinusOne) {
nextChar = *cString++;
cString--;
}
// check for validator
bool isE = (currentChar | ('E' ^ 'e')) == 'e';
bool isValid = VALID_DIGIT(currentChar) || isE || strchr(validChars, currentChar) != NULL;
// in order to work out the split, its either because the next char is
// a hyphen or a plus, or next char is a decimal and the current number is a decimal
bool nIsSign = nextChar == '-' || nextChar == '+';
bool wantsEnd = nIsSign || (nextChar == '.' && isDecimal);
// work our what the sequence is...
IJSVGPathDataSequence seq = kIJSVGPathDataSequenceTypeFloat;
if (sequence != NULL) {
seq = sequence[counter % commandLength];
}
// is a flag, consists of one value
// if its invalid, make sure we free the memory
// and return null - or hell breaks lose
if (isValid == YES && seq == kIJSVGPathDataSequenceTypeFlag) {
if (bufferCount != 0 || (currentChar != '0' && currentChar != '1')) {
return NULL;
}
wantsEnd = YES;
}
// could be a float like 5.334e-5 so dont break on the hypen
if (wantsEnd && isE && nIsSign) {
wantsEnd = false;
}
// make sure its a valid string
if (isValid == YES) {
// alloc the buffer if needed
if ((bufferCount + 1) == dataStream->charCount) {
// realloc the buffer, incase the string is overflowing the
// allocated memory
dataStream->charCount += IJSVG_STREAM_CHAR_BLOCK_SIZE;
dataStream->charBuffer = (char*)realloc(dataStream->charBuffer,
sizeof(char) * dataStream->charCount);
}
// set the actual char against it
if (currentChar == '.') {
isDecimal = true;
}
dataStream->charBuffer[bufferCount++] = currentChar;
} else {
// if its an invalid char, just stop it
wantsEnd = true;
}
// is at end of string, or wants to be stopped
// buffer has to actually exist or its completly
// useless and will cause a crash
if (bufferCount != 0 && (wantsEnd || i == sLengthMinusOne)) {
// make sure there is enough room in the float pool
if ((counter + 1) == dataStream->floatCount) {
dataStream->floatCount += IJSVG_STREAM_FLOAT_BLOCK_SIZE;
dataStream->floatBuffer = (CGFloat*)realloc(dataStream->floatBuffer,
sizeof(CGFloat) * dataStream->floatCount);
}
// add the float - for performance reasons, we can simply set the
// null value of the end of the string instead of nulling out
// with memset \0 - huzzah!
dataStream->charBuffer[bufferCount] = '\0';
dataStream->floatBuffer[counter++] = IJSVGParseFloat(dataStream->charBuffer);
// reset
isDecimal = false;
bufferCount = 0;
}
i++;
}
// set commands found - only if there is one
if (commandsFound != NULL) {
*commandsFound = (NSInteger)round(counter / commandLength);
}
// allocate the new buffer from memory
CGFloat* floats = (CGFloat*)malloc(sizeof(CGFloat) * counter);
memcpy(floats, dataStream->floatBuffer, counter * sizeof(CGFloat));
// return the floats just set into the memory
return floats;
}
// this method is finely tuned to just handle the buffer
// that IJSVGParsePathDataSequence produces for each float
// it does not look or skip white space as the previous method
// handles this for us
// inspired and modified from http://www.leapsecond.com/tools/fast_atof.c
CGFloat IJSVGParseFloat(char* buffer)
{
int fraction;
double sign, value, scale;
// work out a sign, if any, might not be, who knows
sign = 1.f;
if (*buffer == '-') {
sign = -1.f;
buffer += 1;
} else if (*buffer == '+') {
buffer += 1;
}
// get numbers before decimal point or exponent
for (value = 0.f; VALID_DIGIT(*buffer); buffer += 1) {
value = value * 10.f + (*buffer - '0');
}
// get digits after decimal point
if (*buffer == '.') {
double pow10 = 10.f;
buffer += 1;
while (VALID_DIGIT(*buffer)) {
value += (*buffer - '0') / pow10;
pow10 *= 10.f;
buffer += 1;
}
}
// handle exponent
fraction = 0;
scale = 1.f;
if ((*buffer | ('E' ^ 'e')) == 'e') {
unsigned int exponent;
buffer += 1;
if (*buffer == '-') {
fraction = 1;
buffer += 1;
} else if (*buffer == '+') {
buffer += 1;
}
for (exponent = 0; VALID_DIGIT(*buffer); buffer += 1) {
exponent = exponent * 10 + (*buffer - '0');
}
if (exponent > 308) {
exponent = 308;
}
while (exponent >= 50) {
scale *= 1E50;
exponent -= 50;
}
while (exponent >= 8) {
scale *= 1E8;
exponent -= 8;
}
while (exponent > 0) {
scale *= 10.f;
exponent -= 1;
}
}
// make sure we cast this to a CGFloat before return
return (CGFloat)(sign * (fraction ? (value / scale) : (value * scale)));
}
@end
@@ -96,13 +96,14 @@ static NSString const* IJSVGAttributePoints = @"points";
NSMutableDictionary* _defNodes;
NSMutableDictionary* _baseDefNodes;
NSMutableArray<IJSVG*>* _svgs;
NSMutableArray* _definedGroups;
struct {
unsigned int shouldHandleForeignObject : 1;
unsigned int handleForeignObject : 1;
unsigned int handleSubSVG : 1;
} _respondsTo;
IJSVGPathDataStream* _commandDataStream;
}
@property (nonatomic, readonly) NSRect viewBox;
@@ -45,8 +45,10 @@
(void)([_parsedNodes release]), _parsedNodes = nil;
(void)([_defNodes release]), _defNodes = nil;
(void)([_baseDefNodes release]), _baseDefNodes = nil;
(void)([_definedGroups release]), _definedGroups = nil;
(void)([_svgs release]), _svgs = nil;
if (_commandDataStream != NULL) {
(void)IJSVGPathDataStreamRelease(_commandDataStream), _commandDataStream = nil;
}
[super dealloc];
}
@@ -61,6 +63,7 @@
_respondsTo.shouldHandleForeignObject = [_delegate respondsToSelector:@selector(svgParser:shouldHandleForeignObject:)];
_respondsTo.handleSubSVG = [_delegate respondsToSelector:@selector(svgParser:foundSubSVG:withSVGString:)];
_commandDataStream = IJSVGPathDataStreamCreateDefault();
_glyphs = [[NSMutableArray alloc] init];
_parsedNodes = [[NSMutableArray alloc] init];
_defNodes = [[NSMutableDictionary alloc] init];
@@ -240,6 +243,7 @@
(void)([_styleSheet release]), _styleSheet = nil;
(void)([_parsedNodes release]), _parsedNodes = nil;
(void)([_defNodes release]), _defNodes = nil;
(void)IJSVGPathDataStreamRelease(_commandDataStream), _commandDataStream = NULL;
}
- (void)_postParseElementForCommonAttributes:(NSXMLElement*)element
@@ -466,10 +470,6 @@
[self _parseBaseBlock:parseElement
intoGroup:group
def:NO];
if (_definedGroups == nil) {
_definedGroups = [[NSMutableArray alloc] init];
}
[_definedGroups addObject:group];
return [group defForID:anID];
}
return nil;
@@ -1064,7 +1064,8 @@
ignoreAttributes:nil];
// from base64
[image loadFromBase64EncodedString:[[element attributeForName:(NSString*)IJSVGAttributeXLink] stringValue]];
NSString* string = [element attributeForName:(NSString*)IJSVGAttributeXLink].stringValue;
[image loadFromBase64EncodedString:string];
// add to parent
[parentGroup addChild:image];
@@ -1107,43 +1108,39 @@
intoPath:(IJSVGPath*)path
{
// invalid command
if (command == nil || command.length == 0) {
return;
}
NSUInteger len = [command length];
// allocate memory for the string buffer for reading
const char* buffer = [command cStringUsingEncoding:NSUTF8StringEncoding];
int defaultBufferSize = 200;
int currentBufferSize = 0;
int currentSize = defaultBufferSize;
unichar* commandBuffer = NULL;
if (len != 0) {
commandBuffer = (unichar*)calloc(defaultBufferSize, sizeof(unichar));
}
NSUInteger len = command.length;
NSUInteger lastIndex = len - 1;
const char* buffer = command.UTF8String;
// make sure we plus 1 for the null byte
char* charBuffer = (char*)malloc(sizeof(char) * (len + 1));
NSInteger start = 0;
IJSVGCommand* _currentCommand = nil;
for (int i = 0; i < len; i++) {
unichar currentChar = buffer[i];
unichar nextChar = buffer[i + 1];
BOOL atEnd = i == len - 1;
for (NSInteger i = 0; i < len; i++) {
char nextChar = buffer[i + 1];
BOOL atEnd = i == lastIndex;
BOOL isStartCommand = IJSVGIsLegalCommandCharacter(nextChar);
if ((currentBufferSize + 1) == currentSize) {
currentSize += defaultBufferSize;
commandBuffer = (unichar*)realloc(commandBuffer, sizeof(unichar) * currentSize);
}
commandBuffer[currentBufferSize++] = currentChar;
if (isStartCommand == YES || atEnd == YES) {
NSString* commandString = [NSString stringWithCharacters:commandBuffer
length:currentBufferSize];
// 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
NSString* commandString = [NSString stringWithUTF8String:charBuffer];
// reset start position
start = (i + 1);
// previous command is actual subcommand
IJSVGCommand* previousCommand = [_currentCommand subCommands].lastObject;
IJSVGCommand* previousCommand = _currentCommand.subCommands.lastObject;
IJSVGCommand* cCommand = [self _parseCommandString:commandString
previousCommand:previousCommand
intoPath:path];
@@ -1152,16 +1149,9 @@
if (cCommand != nil) {
_currentCommand = cCommand;
}
if (atEnd == NO) {
currentBufferSize = 0;
memset(commandBuffer, '\0', sizeof(unichar) * currentSize);
}
}
}
// free the buffer
free(commandBuffer);
free(charBuffer);
}
- (IJSVGCommand*)_parseCommandString:(NSString*)string
@@ -1179,8 +1169,9 @@
// main commands
// Class commandClass = [IJSVGCommand classFor]
Class commandClass = [IJSVGCommand commandClassForCommandChar:[string characterAtIndex:0]];
IJSVGCommand* command = (IJSVGCommand*)[[[commandClass alloc] initWithCommandString:string] autorelease];
for (IJSVGCommand* subCommand in [command subCommands]) {
IJSVGCommand* command = (IJSVGCommand*)[[[commandClass alloc] initWithCommandString:string
dataStream:_commandDataStream] autorelease];
for (IJSVGCommand* subCommand in command.subCommands) {
[command.class runWithParams:subCommand.parameters
paramCount:subCommand.parameterCount
command:subCommand
@@ -1197,6 +1188,7 @@
{
// convert a line into a command,
// basically MX1 Y1LX2 Y2
path.primitiveType = kIJSVGPrimitivePathTypeLine;
CGFloat x1 = [element attributeForName:(NSString*)IJSVGAttributeX1].stringValue.floatValue;
CGFloat y1 = [element attributeForName:(NSString*)IJSVGAttributeY1].stringValue.floatValue;
CGFloat x2 = [element attributeForName:(NSString*)IJSVGAttributeX2].stringValue.floatValue;
@@ -1214,27 +1206,30 @@
- (void)_parseCircle:(NSXMLElement*)element
intoPath:(IJSVGPath*)path
{
path.primitiveType = kIJSVGPrimitivePathTypeCircle;
CGFloat cX = [element attributeForName:(NSString*)IJSVGAttributeCX].stringValue.floatValue;
CGFloat cY = [element attributeForName:(NSString*)IJSVGAttributeCY].stringValue.floatValue;
CGFloat r = [element attributeForName:(NSString*)IJSVGAttributeR].stringValue.floatValue;
NSRect rect = NSMakeRect(cX - r, cY - r, r * 2, r * 2);
[path overwritePath:[NSBezierPath bezierPathWithOvalInRect:rect]];
path.path = [NSBezierPath bezierPathWithOvalInRect:rect];
}
- (void)_parseEllipse:(NSXMLElement*)element
intoPath:(IJSVGPath*)path
{
path.primitiveType = kIJSVGPrimitivePathTypeEllipse;
CGFloat cX = [element attributeForName:(NSString*)IJSVGAttributeCX].stringValue.floatValue;
CGFloat cY = [element attributeForName:(NSString*)IJSVGAttributeCY].stringValue.floatValue;
CGFloat rX = [element attributeForName:(NSString*)IJSVGAttributeRX].stringValue.floatValue;
CGFloat rY = [element attributeForName:(NSString*)IJSVGAttributeRY].stringValue.floatValue;
NSRect rect = NSMakeRect(cX - rX, cY - rY, rX * 2, rY * 2);
[path overwritePath:[NSBezierPath bezierPathWithOvalInRect:rect]];
path.path = [NSBezierPath bezierPathWithOvalInRect:rect];
}
- (void)_parsePolyline:(NSXMLElement*)element
intoPath:(IJSVGPath*)path
{
path.primitiveType = kIJSVGPrimitivePathTypePolyLine;
[self _parsePoly:element
intoPath:path
closePath:NO];
@@ -1243,6 +1238,7 @@
- (void)_parsePolygon:(NSXMLElement*)element
intoPath:(IJSVGPath*)path
{
path.primitiveType = kIJSVGPrimitivePathTypePolygon;
[self _parsePoly:element
intoPath:path
closePath:YES];
@@ -1252,18 +1248,23 @@
intoPath:(IJSVGPath*)path
closePath:(BOOL)closePath
{
NSString* points = [[element attributeForName:(NSString*)IJSVGAttributePoints] stringValue];
NSString* points = [element attributeForName:(NSString*)IJSVGAttributePoints].stringValue;
NSInteger count = 0;
CGFloat* params = [IJSVGUtils commandParameters:points
count:&count];
// error occured, free the params
if ((count % 2) != 0) {
// error occured, free the params
free(params);
return;
}
// construct a command
NSMutableString* str = [[[NSMutableString alloc] init] autorelease];
NSInteger capacity = count / 2;
if (closePath == YES) {
capacity += 1;
}
NSMutableString* str = [[[NSMutableString alloc] initWithCapacity:capacity] autorelease];
[str appendFormat:@"M%f,%f L", params[0], params[1]];
for (NSInteger i = 2; i < count; i += 2) {
[str appendFormat:@"%f,%f ", params[i], params[i + 1]];
@@ -1279,18 +1280,18 @@
- (void)_parseRect:(NSXMLElement*)element
intoPath:(IJSVGPath*)path
{
path.primitiveType = kIJSVGPrimitivePathTypeRect;
// width and height
CGFloat width = [IJSVGUtils floatValue:[[element attributeForName:(NSString*)IJSVGAttributeWidth] stringValue]
CGFloat width = [IJSVGUtils floatValue:[element attributeForName:(NSString*)IJSVGAttributeWidth].stringValue
fallBackForPercent:self.viewBox.size.width];
CGFloat height = [IJSVGUtils floatValue:[[element attributeForName:(NSString*)IJSVGAttributeHeight] stringValue]
CGFloat height = [IJSVGUtils floatValue:[element attributeForName:(NSString*)IJSVGAttributeHeight].stringValue
fallBackForPercent:self.viewBox.size.height];
// rect uses x and y as start of path, not move path object -_-
CGFloat x = [IJSVGUtils floatValue:[[element attributeForName:(NSString*)IJSVGAttributeX] stringValue]
CGFloat x = [IJSVGUtils floatValue:[element attributeForName:(NSString*)IJSVGAttributeX].stringValue
fallBackForPercent:self.viewBox.size.width];
CGFloat y = [IJSVGUtils floatValue:[[element attributeForName:(NSString*)IJSVGAttributeY] stringValue]
CGFloat y = [IJSVGUtils floatValue:[element attributeForName:(NSString*)IJSVGAttributeY].stringValue
fallBackForPercent:self.viewBox.size.height];
// radius
@@ -1299,11 +1300,9 @@
if ([element attributeForName:(NSString*)IJSVGAttributeRY] == nil) {
rY = rX;
}
NSBezierPath* newPath = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(x, y, width, height)
xRadius:rX
yRadius:rY];
[path overwritePath:newPath];
path.path = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(x, y, width, height)
xRadius:rX
yRadius:rY];
}
@end
@@ -203,6 +203,7 @@
{
// setup path and layer
IJSVGShapeLayer* layer = [[[IJSVGShapeLayer alloc] init] autorelease];
layer.primitiveType = path.primitiveType;
CGPathRef introPath = path.CGPath;
*originalBoundingBox = CGRectIntegral(CGPathGetBoundingBox(introPath));
@@ -742,19 +743,4 @@
}
}
+ (void)log:(IJSVGLayer*)layer
depth:(NSInteger)depth
{
NSLog(@"%@%@: %@, Transforms: %@", [@"" stringByPaddingToLength:depth
withString:@"\t"
startingAtIndex:0],
layer,
NSStringFromRect(layer.frame),
[IJSVGTransform affineTransformToSVGTransformAttributeString:layer.affineTransform]);
for (IJSVGLayer* sublayer in layer.sublayers) {
[self log:(IJSVGLayer*)sublayer
depth:depth++];
}
}
@end
@@ -11,9 +11,9 @@
typedef CGFloat (^IJSVGRenderingBackingScaleFactorHelper)(void);
typedef NS_ENUM(NSInteger, IJSVGRenderQuality) {
IJSVGRenderQualityFullResolution, // slowest to render
IJSVGRenderQualityOptimized, // best of both worlds
IJSVGRenderQualityLow // fast rendering
kIJSVGRenderQualityFullResolution, // slowest to render
kIJSVGRenderQualityOptimized, // best of both worlds
kIJSVGRenderQualityLow // fast rendering
};
@interface IJSVGRendering : NSObject

Some files were not shown because too many files have changed in this diff Show More