Compare commits
142 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 27c4638fa7 | |||
| 7c8bfa937e | |||
| fdc30123a4 | |||
| 80ef3790d2 | |||
| ded0c9b839 | |||
| 6585501f5d | |||
| 846f0fe27c | |||
| 0c64626e3e | |||
| 9ea09ebeee | |||
| 0c04202ad1 | |||
| e66ee5e5a1 | |||
| a97272252d | |||
| a95a046c64 | |||
| d4d8fcfe78 | |||
| e75d862430 | |||
| 44358cc00a | |||
| c7e490fcba | |||
| 63d682f5d9 | |||
| 13a7fb5431 | |||
| f52ee76e2d | |||
| 9c1ad0b44b | |||
| c608d01fa4 | |||
| bb8b3f915b | |||
| ad78aa6598 | |||
| d558f90932 | |||
| e7716dbd7b | |||
| 1d0fce8f2a | |||
| 24825d867d | |||
| 3b63e225c3 | |||
| 1f852e0cf9 | |||
| 2547f47126 | |||
| 4769ebeac7 | |||
| fe51568c83 | |||
| b91235323b | |||
| cefc304e6e | |||
| a23425c9b6 | |||
| 2f2c61e559 | |||
| 061a5fb52c | |||
| 8598bea11e | |||
| faac432117 | |||
| 29a5c5e533 | |||
| f286f4e993 | |||
| 6bbd213eb0 | |||
| c82db3469e | |||
| 8269727063 | |||
| a3d2c6dca9 | |||
| 1c61ab18e4 | |||
| 64588b6e6d | |||
| 3c81cd6634 | |||
| 258c79d208 | |||
| 5228c87f16 | |||
| 05ec5c5a29 | |||
| 8628b38938 | |||
| 3cc8f1f355 | |||
| c7b56ba877 | |||
| e25b00efb7 | |||
| 37d6cc7fd8 | |||
| b2eaf7ead5 | |||
| f60f07ae70 | |||
| bb9ea4ade8 | |||
| d4f96823ec | |||
| c1b024f7a7 | |||
| 2aa004f4b2 | |||
| 4a80c51070 | |||
| c8a813a29e | |||
| 6ca015aeb7 | |||
| 3647c91ab2 | |||
| ee66d25b9e | |||
| 03dfc7deb6 | |||
| 1b75f8964d | |||
| 1506840957 | |||
| ae7e1e0196 | |||
| 20589bfd83 | |||
| 96156fe1e0 | |||
| daf843dd26 | |||
| 8789c7cef7 | |||
| 551548579c | |||
| 5206052905 | |||
| 6ee54e42bb | |||
| 38d7fe15ea | |||
| 0905545edc | |||
| 3ae7f1b6d5 | |||
| 23f861584c | |||
| 94b7e3fe87 | |||
| df7ceb3df1 | |||
| 3efea34d76 | |||
| 7f74e66e90 | |||
| 35473e11c9 | |||
| 4d00aab469 | |||
| bea50a033a | |||
| fe9226a921 | |||
| fa62c7d334 | |||
| 3f58044f9d | |||
| 96218c3fbe | |||
| d1b2fc882d | |||
| 008c70079f | |||
| 05677c7c82 | |||
| 8042ed7dc7 | |||
| ff0b7e0866 | |||
| 304cac0a09 | |||
| 832527134f | |||
| 8657228b26 | |||
| 28c36337c2 | |||
| 44504371ea | |||
| 566527b6c0 | |||
| e235b833ed | |||
| 60547feb98 | |||
| 153258fa31 | |||
| 77741e3f38 | |||
| 22983a33a7 | |||
| e9421025d9 | |||
| 33bd390f94 | |||
| 767ecb0b62 | |||
| 2afae1516a | |||
| 6f9412c3c0 | |||
| fac780b47a | |||
| 2f7c34cf68 | |||
| f2c50ec5a4 | |||
| 3cc75701fc | |||
| 5ba7e94d24 | |||
| 4e53a2cfa9 | |||
| a1eb04ab1d | |||
| 88d7bd048d | |||
| 0dd8e1755e | |||
| e34f28cbda | |||
| f7a566d078 | |||
| 7ebfa75ccd | |||
| 84ade44557 | |||
| 1f0d0b41dc | |||
| 4c280e9694 | |||
| 240a62127c | |||
| 7eb2e12164 | |||
| 2224a2538d | |||
| 7513fc92fd | |||
| 7a0390b377 | |||
| 1cefc6aeed | |||
| 824e87d69a | |||
| e80088fc71 | |||
| 46ba1ddcbd | |||
| 533c369eb8 | |||
| 5ac8aa8760 | |||
| b6ebd598e7 |
@@ -0,0 +1,5 @@
|
||||
framework module IJSVG {
|
||||
umbrella header "IJSVGUmbrella.h"
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
@@ -3,53 +3,76 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 50;
|
||||
objectVersion = 54;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
590AA08D280DDD90002BBE12 /* IJSVGFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 590AA08B280DDD90002BBE12 /* IJSVGFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
590AA08E280DDD90002BBE12 /* IJSVGFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 590AA08C280DDD90002BBE12 /* IJSVGFilter.m */; };
|
||||
590AA091280DDDA3002BBE12 /* IJSVGFilterEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 590AA08F280DDDA3002BBE12 /* IJSVGFilterEffect.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
590AA092280DDDA3002BBE12 /* IJSVGFilterEffect.m in Sources */ = {isa = PBXBuildFile; fileRef = 590AA090280DDDA3002BBE12 /* IJSVGFilterEffect.m */; };
|
||||
590AA096280DE668002BBE12 /* IJSVGFilterEffectGaussianBlur.h in Headers */ = {isa = PBXBuildFile; fileRef = 590AA094280DE668002BBE12 /* IJSVGFilterEffectGaussianBlur.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
590AA097280DE668002BBE12 /* IJSVGFilterEffectGaussianBlur.m in Sources */ = {isa = PBXBuildFile; fileRef = 590AA095280DE668002BBE12 /* IJSVGFilterEffectGaussianBlur.m */; };
|
||||
590EB7A427F637EF0047CECF /* IJSVGTransformLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 590EB7A227F637EF0047CECF /* IJSVGTransformLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
590EB7A527F637EF0047CECF /* IJSVGTransformLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 590EB7A327F637EF0047CECF /* IJSVGTransformLayer.m */; };
|
||||
5910A9A628427AD600BD1F03 /* IJSVGMask.h in Headers */ = {isa = PBXBuildFile; fileRef = 5910A9A428427AD600BD1F03 /* IJSVGMask.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
5910A9A728427AD600BD1F03 /* IJSVGMask.m in Sources */ = {isa = PBXBuildFile; fileRef = 5910A9A528427AD600BD1F03 /* IJSVGMask.m */; };
|
||||
5910A9AA284377D600BD1F03 /* IJSVGClipPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 5910A9A8284377D600BD1F03 /* IJSVGClipPath.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
5910A9AB284377D600BD1F03 /* IJSVGClipPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 5910A9A9284377D600BD1F03 /* IJSVGClipPath.m */; };
|
||||
5919111E28C7F1160047791B /* IJSVGBitFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 5919111C28C7F1160047791B /* IJSVGBitFlags.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
5919111F28C7F1160047791B /* IJSVGBitFlags.m in Sources */ = {isa = PBXBuildFile; fileRef = 5919111D28C7F1160047791B /* IJSVGBitFlags.m */; };
|
||||
5919E65723F47FF60051873A /* IJSVGUnitRect.h in Headers */ = {isa = PBXBuildFile; fileRef = 5919E65523F47FF60051873A /* IJSVGUnitRect.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
5919E65823F47FF60051873A /* IJSVGUnitRect.m in Sources */ = {isa = PBXBuildFile; fileRef = 5919E65623F47FF60051873A /* IJSVGUnitRect.m */; };
|
||||
5919E65B23F480330051873A /* IJSVGUnitPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5919E65923F480330051873A /* IJSVGUnitPoint.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
5919E65C23F480330051873A /* IJSVGUnitPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = 5919E65A23F480330051873A /* IJSVGUnitPoint.m */; };
|
||||
591A3E4D25CC91F800AD45B7 /* IJSVGParsing.h in Headers */ = {isa = PBXBuildFile; fileRef = 591A3E4B25CC91F800AD45B7 /* IJSVGParsing.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
591A3E4E25CC91F800AD45B7 /* IJSVGParsing.m in Sources */ = {isa = PBXBuildFile; fileRef = 591A3E4C25CC91F800AD45B7 /* IJSVGParsing.m */; };
|
||||
5926079F287D6C1000E93B09 /* IJSVGFeatureFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 5926079D287D6C1000E93B09 /* IJSVGFeatureFlags.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
592607A0287D6C1000E93B09 /* IJSVGFeatureFlags.m in Sources */ = {isa = PBXBuildFile; fileRef = 5926079E287D6C1000E93B09 /* IJSVGFeatureFlags.m */; };
|
||||
594A10DA248D7C90001A3181 /* NSImage+IJSVGAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 594A10D8248D7C90001A3181 /* NSImage+IJSVGAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
594A10DB248D7C90001A3181 /* NSImage+IJSVGAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 594A10D9248D7C90001A3181 /* NSImage+IJSVGAdditions.m */; };
|
||||
594CF55F238FF462009B251B /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF55E238FF462009B251B /* AppKit.framework */; };
|
||||
594CF561238FF46C009B251B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF560238FF46C009B251B /* Foundation.framework */; };
|
||||
594CF563238FF473009B251B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF562238FF473009B251B /* QuartzCore.framework */; };
|
||||
5955731F286C643900156047 /* IJSVGTileLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5955731D286C643900156047 /* IJSVGTileLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59557320286C643900156047 /* IJSVGTileLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5955731E286C643900156047 /* IJSVGTileLayer.m */; };
|
||||
595BA91C280EB29B00AD1C89 /* IJSVGFilterLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 595BA91A280EB29B00AD1C89 /* IJSVGFilterLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
595BA91D280EB29B00AD1C89 /* IJSVGFilterLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 595BA91B280EB29B00AD1C89 /* IJSVGFilterLayer.m */; };
|
||||
595FD12F29EC56BA00666897 /* IJSVGUmbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 595FD12E29EC56BA00666897 /* IJSVGUmbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
5978C46A280A241200D25296 /* IJSVGRootLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5978C468280A241200D25296 /* IJSVGRootLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
5978C46B280A241200D25296 /* IJSVGRootLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5978C469280A241200D25296 /* IJSVGRootLayer.m */; };
|
||||
599EB4D3238FF570004CB6BC /* libobjc.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 599EB4D2238FF535004CB6BC /* libobjc.tbd */; };
|
||||
59A24EBC23F480EA0090C374 /* IJSVGUnitSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 59A24EBA23F480EA0090C374 /* IJSVGUnitSize.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59A24EBD23F480EA0090C374 /* IJSVGUnitSize.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A24EBB23F480EA0090C374 /* IJSVGUnitSize.m */; };
|
||||
59AC865A2810156B00CD5685 /* IJSVGThreadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 59AC86582810156B00CD5685 /* IJSVGThreadManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59AC865B2810156B00CD5685 /* IJSVGThreadManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 59AC86592810156B00CD5685 /* IJSVGThreadManager.m */; };
|
||||
59DB84E028C9F70000A9696A /* IJSVGBitFlags64.h in Headers */ = {isa = PBXBuildFile; fileRef = 59DB84DE28C9F70000A9696A /* IJSVGBitFlags64.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59DB84E128C9F70000A9696A /* IJSVGBitFlags64.m in Sources */ = {isa = PBXBuildFile; fileRef = 59DB84DF28C9F70000A9696A /* IJSVGBitFlags64.m */; };
|
||||
59E6690D287D6C810085EDF5 /* IJSVGFeatureFlag.h in Headers */ = {isa = PBXBuildFile; fileRef = 59E6690B287D6C810085EDF5 /* IJSVGFeatureFlag.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59E6690E287D6C810085EDF5 /* IJSVGFeatureFlag.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E6690C287D6C810085EDF5 /* IJSVGFeatureFlag.m */; };
|
||||
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 */; };
|
||||
59EB75D923905F7300F5AE63 /* IJSVGCommandLineTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756823905F6B00F5AE63 /* IJSVGCommandLineTo.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75DA23905F7300F5AE63 /* IJSVGDef.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB756923905F6B00F5AE63 /* IJSVGDef.m */; };
|
||||
59EB75DB23905F7300F5AE63 /* IJSVG.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756A23905F6B00F5AE63 /* IJSVG.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75DC23905F7300F5AE63 /* IJSVGText.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756B23905F6B00F5AE63 /* IJSVGText.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75DD23905F7300F5AE63 /* IJSVGCommandQuadraticCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB756C23905F6B00F5AE63 /* IJSVGCommandQuadraticCurve.m */; };
|
||||
59EB75DE23905F7300F5AE63 /* IJSVGCommandVerticalLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756D23905F6C00F5AE63 /* IJSVGCommandVerticalLine.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75E023905F7300F5AE63 /* IJSVGStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756F23905F6C00F5AE63 /* IJSVGStyleSheet.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75E123905F7300F5AE63 /* IJSVGCommandSmoothCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757023905F6C00F5AE63 /* IJSVGCommandSmoothCurve.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75E223905F7300F5AE63 /* IJSVGColorList.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757123905F6C00F5AE63 /* IJSVGColorList.m */; };
|
||||
59EB75E223905F7300F5AE63 /* IJSVGTraitedColorStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757123905F6C00F5AE63 /* IJSVGTraitedColorStorage.m */; };
|
||||
59EB75E323905F7300F5AE63 /* IJSVGRadialGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757223905F6C00F5AE63 /* IJSVGRadialGradient.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75E423905F7300F5AE63 /* IJSVGGradientUnitLength.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757323905F6C00F5AE63 /* IJSVGGradientUnitLength.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75E523905F7300F5AE63 /* IJSVGStrokeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757423905F6C00F5AE63 /* IJSVGStrokeLayer.m */; };
|
||||
59EB75E623905F7300F5AE63 /* IJSVGStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757523905F6C00F5AE63 /* IJSVGStyle.m */; };
|
||||
59EB75E623905F7300F5AE63 /* IJSVGStyleSheetStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757523905F6C00F5AE63 /* IJSVGStyleSheetStyle.m */; };
|
||||
59EB75E723905F7300F5AE63 /* IJSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757623905F6C00F5AE63 /* IJSVGImage.m */; };
|
||||
59EB75E823905F7300F5AE63 /* IJSVGUnitLength.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757723905F6C00F5AE63 /* IJSVGUnitLength.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75E923905F7300F5AE63 /* IJSVGStringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757823905F6C00F5AE63 /* IJSVGStringAdditions.m */; };
|
||||
59EB75EA23905F7300F5AE63 /* IJSVGTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757923905F6C00F5AE63 /* IJSVGTransaction.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75EB23905F7300F5AE63 /* IJSVGShapeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757A23905F6C00F5AE63 /* IJSVGShapeLayer.m */; };
|
||||
59EB75EC23905F7300F5AE63 /* IJSVGLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757B23905F6C00F5AE63 /* IJSVGLayer.m */; };
|
||||
59EB75ED23905F7300F5AE63 /* IJSVGFontConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757C23905F6C00F5AE63 /* IJSVGFontConverter.m */; };
|
||||
59EB75EE23905F7300F5AE63 /* IJSVGImageRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757D23905F6C00F5AE63 /* IJSVGImageRep.m */; };
|
||||
59EB75EF23905F7300F5AE63 /* IJSVGCommandQuadraticCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757E23905F6C00F5AE63 /* IJSVGCommandQuadraticCurve.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75F023905F7300F5AE63 /* IJSVGStyleSheetSelectorRaw.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757F23905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -59,13 +82,11 @@
|
||||
59EB75F423905F7300F5AE63 /* IJSVGColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB758323905F6C00F5AE63 /* IJSVGColor.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75F523905F7300F5AE63 /* IJSVGError.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB758423905F6C00F5AE63 /* IJSVGError.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75F623905F7300F5AE63 /* IJSVGColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758523905F6C00F5AE63 /* IJSVGColor.m */; };
|
||||
59EB75F723905F7300F5AE63 /* IJSVGDef.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB758623905F6C00F5AE63 /* IJSVGDef.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75F823905F7300F5AE63 /* IJSVGCommandHorizontalLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758723905F6C00F5AE63 /* IJSVGCommandHorizontalLine.m */; };
|
||||
59EB75F923905F7300F5AE63 /* IJSVGFontConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB758823905F6D00F5AE63 /* IJSVGFontConverter.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75FB23905F7300F5AE63 /* IJSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758A23905F6D00F5AE63 /* IJSVGPath.m */; };
|
||||
59EB75FC23905F7300F5AE63 /* IJSVGGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB758B23905F6D00F5AE63 /* IJSVGGroup.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB75FD23905F7300F5AE63 /* IJSVGPatternLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758C23905F6D00F5AE63 /* IJSVGPatternLayer.m */; };
|
||||
59EB75FE23905F7300F5AE63 /* IJSVGRenderingStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758D23905F6D00F5AE63 /* IJSVGRenderingStyle.m */; };
|
||||
59EB75FE23905F7300F5AE63 /* IJSVGStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758D23905F6D00F5AE63 /* IJSVGStyle.m */; };
|
||||
59EB760023905F7300F5AE63 /* IJSVGGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758F23905F6D00F5AE63 /* IJSVGGradientLayer.m */; };
|
||||
59EB760123905F7300F5AE63 /* IJSVGLayerTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759023905F6D00F5AE63 /* IJSVGLayerTree.m */; };
|
||||
59EB760223905F7300F5AE63 /* IJSVGCommandVerticalLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759123905F6D00F5AE63 /* IJSVGCommandVerticalLine.m */; };
|
||||
@@ -83,7 +104,7 @@
|
||||
59EB760F23905F7300F5AE63 /* IJSVGCommandEllipticalArc.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759E23905F6E00F5AE63 /* IJSVGCommandEllipticalArc.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761023905F7300F5AE63 /* IJSVGLinearGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759F23905F6E00F5AE63 /* IJSVGLinearGradient.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761123905F7300F5AE63 /* IJSVGCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75A023905F6E00F5AE63 /* IJSVGCommand.m */; };
|
||||
59EB761223905F7300F5AE63 /* IJSVGRenderingStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A123905F6E00F5AE63 /* IJSVGRenderingStyle.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761223905F7300F5AE63 /* IJSVGStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A123905F6E00F5AE63 /* IJSVGStyle.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761323905F7300F5AE63 /* IJSVG.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75A223905F6E00F5AE63 /* IJSVG.m */; };
|
||||
59EB761423905F7300F5AE63 /* IJSVGImageRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A323905F6E00F5AE63 /* IJSVGImageRep.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761523905F7300F5AE63 /* IJSVGStrokeLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A423905F6E00F5AE63 /* IJSVGStrokeLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -91,10 +112,10 @@
|
||||
59EB761723905F7300F5AE63 /* IJSVGRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75A623905F6F00F5AE63 /* IJSVGRadialGradient.m */; };
|
||||
59EB761823905F7300F5AE63 /* IJSVGParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A723905F6F00F5AE63 /* IJSVGParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761923905F7300F5AE63 /* IJSVGCommandSmoothCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75A823905F6F00F5AE63 /* IJSVGCommandSmoothCurve.m */; };
|
||||
59EB761A23905F7300F5AE63 /* IJSVGColorList.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A923905F6F00F5AE63 /* IJSVGColorList.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761A23905F7300F5AE63 /* IJSVGTraitedColorStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A923905F6F00F5AE63 /* IJSVGTraitedColorStorage.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761B23905F7300F5AE63 /* IJSVGPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75AA23905F6F00F5AE63 /* IJSVGPattern.m */; };
|
||||
59EB761C23905F7300F5AE63 /* IJSVGGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75AB23905F6F00F5AE63 /* IJSVGGradient.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761D23905F7300F5AE63 /* IJSVGStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75AC23905F6F00F5AE63 /* IJSVGStyle.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761D23905F7300F5AE63 /* IJSVGStyleSheetStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75AC23905F6F00F5AE63 /* IJSVGStyleSheetStyle.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761E23905F7300F5AE63 /* IJSVGGroupLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75AD23905F6F00F5AE63 /* IJSVGGroupLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB761F23905F7300F5AE63 /* IJSVGCommandLineTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75AE23905F6F00F5AE63 /* IJSVGCommandLineTo.m */; };
|
||||
59EB762023905F7300F5AE63 /* IJSVGCommandMove.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75AF23905F6F00F5AE63 /* IJSVGCommandMove.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -134,25 +155,43 @@
|
||||
59EB764423905F7300F5AE63 /* IJSVGRendering.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75D323905F7300F5AE63 /* IJSVGRendering.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB764523905F7300F5AE63 /* IJSVGExporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75D423905F7300F5AE63 /* IJSVGExporter.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59EB764623905F7300F5AE63 /* IJSVGRendering.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75D523905F7300F5AE63 /* IJSVGRendering.m */; };
|
||||
59F36508262F1ABB00BCE3FD /* IJSVGColorType.h in Headers */ = {isa = PBXBuildFile; fileRef = 59F36506262F1ABB00BCE3FD /* IJSVGColorType.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59F36509262F1ABB00BCE3FD /* IJSVGColorType.m in Sources */ = {isa = PBXBuildFile; fileRef = 59F36507262F1ABB00BCE3FD /* IJSVGColorType.m */; };
|
||||
59F36508262F1ABB00BCE3FD /* IJSVGTraitedColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 59F36506262F1ABB00BCE3FD /* IJSVGTraitedColor.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59F36509262F1ABB00BCE3FD /* IJSVGTraitedColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 59F36507262F1ABB00BCE3FD /* IJSVGTraitedColor.m */; };
|
||||
59F38A63280ED99200804FE4 /* IJSVGBasicLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59F38A61280ED99200804FE4 /* IJSVGBasicLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59F38A64280ED99200804FE4 /* IJSVGBasicLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59F38A62280ED99200804FE4 /* IJSVGBasicLayer.m */; };
|
||||
59F9EAF82808BB5F00188ACB /* IJSVGViewBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 59F9EAF62808BB5F00188ACB /* IJSVGViewBox.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59F9EAF92808BB5F00188ACB /* IJSVGViewBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 59F9EAF72808BB5F00188ACB /* IJSVGViewBox.m */; };
|
||||
59FCC09427F2394D00BB924E /* IJSVGRootNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 59FCC09227F2394D00BB924E /* IJSVGRootNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59FCC09527F2394D00BB924E /* IJSVGRootNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 59FCC09327F2394D00BB924E /* IJSVGRootNode.m */; };
|
||||
59FDBF0027F3454800AF7038 /* IJSVGColorNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 59FDBEFE27F3454800AF7038 /* IJSVGColorNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
59FDBF0127F3454800AF7038 /* IJSVGColorNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 59FDBEFF27F3454800AF7038 /* IJSVGColorNode.m */; };
|
||||
59FE8E4328C7E70800AB38B3 /* IJSVGStop.m in Sources */ = {isa = PBXBuildFile; fileRef = 59FE8E4128C7E70800AB38B3 /* IJSVGStop.m */; };
|
||||
59FE8E4428C7E70800AB38B3 /* IJSVGStop.h in Headers */ = {isa = PBXBuildFile; fileRef = 59FE8E4228C7E70800AB38B3 /* IJSVGStop.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
590AA08B280DDD90002BBE12 /* IJSVGFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGFilter.h; sourceTree = "<group>"; };
|
||||
590AA08C280DDD90002BBE12 /* IJSVGFilter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGFilter.m; sourceTree = "<group>"; };
|
||||
590AA08F280DDDA3002BBE12 /* IJSVGFilterEffect.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGFilterEffect.h; sourceTree = "<group>"; };
|
||||
590AA090280DDDA3002BBE12 /* IJSVGFilterEffect.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGFilterEffect.m; sourceTree = "<group>"; };
|
||||
590AA094280DE668002BBE12 /* IJSVGFilterEffectGaussianBlur.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGFilterEffectGaussianBlur.h; sourceTree = "<group>"; };
|
||||
590AA095280DE668002BBE12 /* IJSVGFilterEffectGaussianBlur.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGFilterEffectGaussianBlur.m; sourceTree = "<group>"; };
|
||||
590EB7A227F637EF0047CECF /* IJSVGTransformLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGTransformLayer.h; sourceTree = "<group>"; };
|
||||
590EB7A327F637EF0047CECF /* IJSVGTransformLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGTransformLayer.m; sourceTree = "<group>"; };
|
||||
5910A9A428427AD600BD1F03 /* IJSVGMask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGMask.h; sourceTree = "<group>"; };
|
||||
5910A9A528427AD600BD1F03 /* IJSVGMask.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGMask.m; sourceTree = "<group>"; };
|
||||
5910A9A8284377D600BD1F03 /* IJSVGClipPath.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGClipPath.h; sourceTree = "<group>"; };
|
||||
5910A9A9284377D600BD1F03 /* IJSVGClipPath.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGClipPath.m; sourceTree = "<group>"; };
|
||||
5919111C28C7F1160047791B /* IJSVGBitFlags.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGBitFlags.h; sourceTree = "<group>"; };
|
||||
5919111D28C7F1160047791B /* IJSVGBitFlags.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGBitFlags.m; sourceTree = "<group>"; };
|
||||
5919E65523F47FF60051873A /* IJSVGUnitRect.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGUnitRect.h; sourceTree = "<group>"; };
|
||||
5919E65623F47FF60051873A /* IJSVGUnitRect.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGUnitRect.m; sourceTree = "<group>"; };
|
||||
5919E65923F480330051873A /* IJSVGUnitPoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGUnitPoint.h; sourceTree = "<group>"; };
|
||||
5919E65A23F480330051873A /* IJSVGUnitPoint.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGUnitPoint.m; sourceTree = "<group>"; };
|
||||
591A3E4B25CC91F800AD45B7 /* IJSVGParsing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGParsing.h; sourceTree = "<group>"; };
|
||||
591A3E4C25CC91F800AD45B7 /* IJSVGParsing.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGParsing.m; sourceTree = "<group>"; };
|
||||
5926079D287D6C1000E93B09 /* IJSVGFeatureFlags.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGFeatureFlags.h; sourceTree = "<group>"; };
|
||||
5926079E287D6C1000E93B09 /* IJSVGFeatureFlags.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGFeatureFlags.m; sourceTree = "<group>"; };
|
||||
594A10D8248D7C90001A3181 /* NSImage+IJSVGAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSImage+IJSVGAdditions.h"; sourceTree = "<group>"; };
|
||||
594A10D9248D7C90001A3181 /* NSImage+IJSVGAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSImage+IJSVGAdditions.m"; sourceTree = "<group>"; };
|
||||
594CF46F238FF38E009B251B /* IJSVG.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = IJSVG.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -160,36 +199,46 @@
|
||||
594CF55E238FF462009B251B /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
594CF560238FF46C009B251B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
594CF562238FF473009B251B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
5955731D286C643900156047 /* IJSVGTileLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGTileLayer.h; sourceTree = "<group>"; };
|
||||
5955731E286C643900156047 /* IJSVGTileLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGTileLayer.m; sourceTree = "<group>"; };
|
||||
595BA91A280EB29B00AD1C89 /* IJSVGFilterLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGFilterLayer.h; sourceTree = "<group>"; };
|
||||
595BA91B280EB29B00AD1C89 /* IJSVGFilterLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGFilterLayer.m; sourceTree = "<group>"; };
|
||||
595FD12E29EC56BA00666897 /* IJSVGUmbrella.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGUmbrella.h; sourceTree = "<group>"; };
|
||||
596AB830298854270013110A /* IJSVG.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = IJSVG.modulemap; sourceTree = SOURCE_ROOT; };
|
||||
5978C468280A241200D25296 /* IJSVGRootLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGRootLayer.h; sourceTree = "<group>"; };
|
||||
5978C469280A241200D25296 /* IJSVGRootLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGRootLayer.m; sourceTree = "<group>"; };
|
||||
599EB4D2238FF535004CB6BC /* libobjc.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libobjc.tbd; path = usr/lib/libobjc.tbd; sourceTree = SDKROOT; };
|
||||
59A24EBA23F480EA0090C374 /* IJSVGUnitSize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGUnitSize.h; sourceTree = "<group>"; };
|
||||
59A24EBB23F480EA0090C374 /* IJSVGUnitSize.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGUnitSize.m; sourceTree = "<group>"; };
|
||||
59AC86582810156B00CD5685 /* IJSVGThreadManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGThreadManager.h; sourceTree = "<group>"; };
|
||||
59AC86592810156B00CD5685 /* IJSVGThreadManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGThreadManager.m; sourceTree = "<group>"; };
|
||||
59DB84DE28C9F70000A9696A /* IJSVGBitFlags64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGBitFlags64.h; sourceTree = "<group>"; };
|
||||
59DB84DF28C9F70000A9696A /* IJSVGBitFlags64.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGBitFlags64.m; sourceTree = "<group>"; };
|
||||
59E6690B287D6C810085EDF5 /* IJSVGFeatureFlag.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGFeatureFlag.h; sourceTree = "<group>"; };
|
||||
59E6690C287D6C810085EDF5 /* IJSVGFeatureFlag.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGFeatureFlag.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>"; };
|
||||
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>"; };
|
||||
59EB757123905F6C00F5AE63 /* IJSVGTraitedColorStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGTraitedColorStorage.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>"; };
|
||||
59EB757523905F6C00F5AE63 /* IJSVGStyleSheetStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheetStyle.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>"; };
|
||||
@@ -199,13 +248,11 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
59EB758D23905F6D00F5AE63 /* IJSVGStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyle.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>"; };
|
||||
@@ -223,7 +270,7 @@
|
||||
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>"; };
|
||||
59EB75A123905F6E00F5AE63 /* IJSVGStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyle.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>"; };
|
||||
@@ -231,10 +278,10 @@
|
||||
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>"; };
|
||||
59EB75A923905F6F00F5AE63 /* IJSVGTraitedColorStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGTraitedColorStorage.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>"; };
|
||||
59EB75AC23905F6F00F5AE63 /* IJSVGStyleSheetStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheetStyle.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>"; };
|
||||
@@ -274,14 +321,18 @@
|
||||
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>"; };
|
||||
59F36506262F1ABB00BCE3FD /* IJSVGColorType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGColorType.h; sourceTree = "<group>"; };
|
||||
59F36507262F1ABB00BCE3FD /* IJSVGColorType.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGColorType.m; sourceTree = "<group>"; };
|
||||
59F36506262F1ABB00BCE3FD /* IJSVGTraitedColor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGTraitedColor.h; sourceTree = "<group>"; };
|
||||
59F36507262F1ABB00BCE3FD /* IJSVGTraitedColor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGTraitedColor.m; sourceTree = "<group>"; };
|
||||
59F38A61280ED99200804FE4 /* IJSVGBasicLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGBasicLayer.h; sourceTree = "<group>"; };
|
||||
59F38A62280ED99200804FE4 /* IJSVGBasicLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGBasicLayer.m; sourceTree = "<group>"; };
|
||||
59F9EAF62808BB5F00188ACB /* IJSVGViewBox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGViewBox.h; sourceTree = "<group>"; };
|
||||
59F9EAF72808BB5F00188ACB /* IJSVGViewBox.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGViewBox.m; sourceTree = "<group>"; };
|
||||
59FCC09227F2394D00BB924E /* IJSVGRootNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGRootNode.h; sourceTree = "<group>"; };
|
||||
59FCC09327F2394D00BB924E /* IJSVGRootNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGRootNode.m; sourceTree = "<group>"; };
|
||||
59FDBEFE27F3454800AF7038 /* IJSVGColorNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGColorNode.h; sourceTree = "<group>"; };
|
||||
59FDBEFF27F3454800AF7038 /* IJSVGColorNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGColorNode.m; sourceTree = "<group>"; };
|
||||
59FE8E4128C7E70800AB38B3 /* IJSVGStop.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStop.m; sourceTree = "<group>"; };
|
||||
59FE8E4228C7E70800AB38B3 /* IJSVGStop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStop.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -299,6 +350,15 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
590AA093280DE648002BBE12 /* Filter Effects */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
590AA094280DE668002BBE12 /* IJSVGFilterEffectGaussianBlur.h */,
|
||||
590AA095280DE668002BBE12 /* IJSVGFilterEffectGaussianBlur.m */,
|
||||
);
|
||||
path = "Filter Effects";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
592ABBE223979F9B00F44380 /* Commands */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -331,8 +391,8 @@
|
||||
592ABBE323979FBB00F44380 /* Stylesheets */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
59EB75AC23905F6F00F5AE63 /* IJSVGStyle.h */,
|
||||
59EB757523905F6C00F5AE63 /* IJSVGStyle.m */,
|
||||
59EB75AC23905F6F00F5AE63 /* IJSVGStyleSheetStyle.h */,
|
||||
59EB757523905F6C00F5AE63 /* IJSVGStyleSheetStyle.m */,
|
||||
59EB756F23905F6C00F5AE63 /* IJSVGStyleSheet.h */,
|
||||
59EB75D123905F7300F5AE63 /* IJSVGStyleSheet.m */,
|
||||
59EB759B23905F6E00F5AE63 /* IJSVGStyleSheetRule.h */,
|
||||
@@ -350,10 +410,10 @@
|
||||
children = (
|
||||
59EB758323905F6C00F5AE63 /* IJSVGColor.h */,
|
||||
59EB758523905F6C00F5AE63 /* IJSVGColor.m */,
|
||||
59EB75A923905F6F00F5AE63 /* IJSVGColorList.h */,
|
||||
59EB757123905F6C00F5AE63 /* IJSVGColorList.m */,
|
||||
59F36506262F1ABB00BCE3FD /* IJSVGColorType.h */,
|
||||
59F36507262F1ABB00BCE3FD /* IJSVGColorType.m */,
|
||||
59EB75A923905F6F00F5AE63 /* IJSVGTraitedColorStorage.h */,
|
||||
59EB757123905F6C00F5AE63 /* IJSVGTraitedColorStorage.m */,
|
||||
59F36506262F1ABB00BCE3FD /* IJSVGTraitedColor.h */,
|
||||
59F36507262F1ABB00BCE3FD /* IJSVGTraitedColor.m */,
|
||||
);
|
||||
path = Colors;
|
||||
sourceTree = "<group>";
|
||||
@@ -379,6 +439,12 @@
|
||||
590EB7A327F637EF0047CECF /* IJSVGTransformLayer.m */,
|
||||
5978C468280A241200D25296 /* IJSVGRootLayer.h */,
|
||||
5978C469280A241200D25296 /* IJSVGRootLayer.m */,
|
||||
595BA91A280EB29B00AD1C89 /* IJSVGFilterLayer.h */,
|
||||
595BA91B280EB29B00AD1C89 /* IJSVGFilterLayer.m */,
|
||||
59F38A61280ED99200804FE4 /* IJSVGBasicLayer.h */,
|
||||
59F38A62280ED99200804FE4 /* IJSVGBasicLayer.m */,
|
||||
5955731D286C643900156047 /* IJSVGTileLayer.h */,
|
||||
5955731E286C643900156047 /* IJSVGTileLayer.m */,
|
||||
);
|
||||
path = Layers;
|
||||
sourceTree = "<group>";
|
||||
@@ -397,10 +463,11 @@
|
||||
592ABBE72397A02900F44380 /* Nodes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
590AA093280DE648002BBE12 /* Filter Effects */,
|
||||
59FE8E4228C7E70800AB38B3 /* IJSVGStop.h */,
|
||||
59FE8E4128C7E70800AB38B3 /* IJSVGStop.m */,
|
||||
59EB75CE23905F7200F5AE63 /* IJSVGForeignObject.h */,
|
||||
59EB75C923905F7200F5AE63 /* IJSVGForeignObject.m */,
|
||||
59EB758623905F6C00F5AE63 /* IJSVGDef.h */,
|
||||
59EB756923905F6B00F5AE63 /* IJSVGDef.m */,
|
||||
59EB759F23905F6E00F5AE63 /* IJSVGLinearGradient.h */,
|
||||
59EB75C223905F7100F5AE63 /* IJSVGLinearGradient.m */,
|
||||
59EB757223905F6C00F5AE63 /* IJSVGRadialGradient.h */,
|
||||
@@ -423,6 +490,14 @@
|
||||
59FCC09327F2394D00BB924E /* IJSVGRootNode.m */,
|
||||
59FDBEFE27F3454800AF7038 /* IJSVGColorNode.h */,
|
||||
59FDBEFF27F3454800AF7038 /* IJSVGColorNode.m */,
|
||||
590AA08B280DDD90002BBE12 /* IJSVGFilter.h */,
|
||||
590AA08C280DDD90002BBE12 /* IJSVGFilter.m */,
|
||||
590AA08F280DDDA3002BBE12 /* IJSVGFilterEffect.h */,
|
||||
590AA090280DDDA3002BBE12 /* IJSVGFilterEffect.m */,
|
||||
5910A9A428427AD600BD1F03 /* IJSVGMask.h */,
|
||||
5910A9A528427AD600BD1F03 /* IJSVGMask.m */,
|
||||
5910A9A8284377D600BD1F03 /* IJSVGClipPath.h */,
|
||||
5910A9A9284377D600BD1F03 /* IJSVGClipPath.m */,
|
||||
);
|
||||
path = Nodes;
|
||||
sourceTree = "<group>";
|
||||
@@ -452,6 +527,16 @@
|
||||
591A3E4C25CC91F800AD45B7 /* IJSVGParsing.m */,
|
||||
59F9EAF62808BB5F00188ACB /* IJSVGViewBox.h */,
|
||||
59F9EAF72808BB5F00188ACB /* IJSVGViewBox.m */,
|
||||
59AC86582810156B00CD5685 /* IJSVGThreadManager.h */,
|
||||
59AC86592810156B00CD5685 /* IJSVGThreadManager.m */,
|
||||
5926079D287D6C1000E93B09 /* IJSVGFeatureFlags.h */,
|
||||
5926079E287D6C1000E93B09 /* IJSVGFeatureFlags.m */,
|
||||
59E6690B287D6C810085EDF5 /* IJSVGFeatureFlag.h */,
|
||||
59E6690C287D6C810085EDF5 /* IJSVGFeatureFlag.m */,
|
||||
5919111C28C7F1160047791B /* IJSVGBitFlags.h */,
|
||||
5919111D28C7F1160047791B /* IJSVGBitFlags.m */,
|
||||
59DB84DE28C9F70000A9696A /* IJSVGBitFlags64.h */,
|
||||
59DB84DF28C9F70000A9696A /* IJSVGBitFlags64.m */,
|
||||
);
|
||||
path = Utils;
|
||||
sourceTree = "<group>";
|
||||
@@ -474,8 +559,8 @@
|
||||
59EB759023905F6D00F5AE63 /* IJSVGLayerTree.m */,
|
||||
59EB75D323905F7300F5AE63 /* IJSVGRendering.h */,
|
||||
59EB75D523905F7300F5AE63 /* IJSVGRendering.m */,
|
||||
59EB75A123905F6E00F5AE63 /* IJSVGRenderingStyle.h */,
|
||||
59EB758D23905F6D00F5AE63 /* IJSVGRenderingStyle.m */,
|
||||
59EB75A123905F6E00F5AE63 /* IJSVGStyle.h */,
|
||||
59EB758D23905F6D00F5AE63 /* IJSVGStyle.m */,
|
||||
);
|
||||
path = Rendering;
|
||||
sourceTree = "<group>";
|
||||
@@ -511,6 +596,7 @@
|
||||
594CF471238FF38E009B251B /* IJSVG */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
596AB830298854270013110A /* IJSVG.modulemap */,
|
||||
59EB756423905F3100F5AE63 /* Source */,
|
||||
594CF473238FF38E009B251B /* Info.plist */,
|
||||
);
|
||||
@@ -534,12 +620,11 @@
|
||||
59EB756A23905F6B00F5AE63 /* IJSVG.h */,
|
||||
59EB75A223905F6E00F5AE63 /* IJSVG.m */,
|
||||
59EB758423905F6C00F5AE63 /* IJSVGError.h */,
|
||||
59EB758823905F6D00F5AE63 /* IJSVGFontConverter.h */,
|
||||
59EB757C23905F6C00F5AE63 /* IJSVGFontConverter.m */,
|
||||
59EB75A323905F6E00F5AE63 /* IJSVGImageRep.h */,
|
||||
59EB757D23905F6C00F5AE63 /* IJSVGImageRep.m */,
|
||||
59EB75CD23905F7200F5AE63 /* IJSVGView.h */,
|
||||
59EB75C123905F7100F5AE63 /* IJSVGView.m */,
|
||||
595FD12E29EC56BA00666897 /* IJSVGUmbrella.h */,
|
||||
);
|
||||
path = Core;
|
||||
sourceTree = "<group>";
|
||||
@@ -578,14 +663,13 @@
|
||||
59EB764423905F7300F5AE63 /* IJSVGRendering.h in Headers */,
|
||||
59EB75DC23905F7300F5AE63 /* IJSVGText.h in Headers */,
|
||||
59EB761C23905F7300F5AE63 /* IJSVGGradient.h in Headers */,
|
||||
59EB75F923905F7300F5AE63 /* IJSVGFontConverter.h in Headers */,
|
||||
59EB75EF23905F7300F5AE63 /* IJSVGCommandQuadraticCurve.h in Headers */,
|
||||
59EB75FC23905F7300F5AE63 /* IJSVGGroup.h in Headers */,
|
||||
59EB760323905F7300F5AE63 /* IJSVGNode.h in Headers */,
|
||||
59EB762023905F7300F5AE63 /* IJSVGCommandMove.h in Headers */,
|
||||
59EB762C23905F7300F5AE63 /* IJSVGPattern.h in Headers */,
|
||||
59EB762923905F7300F5AE63 /* IJSVGStringAdditions.h in Headers */,
|
||||
59EB761A23905F7300F5AE63 /* IJSVGColorList.h in Headers */,
|
||||
59EB761A23905F7300F5AE63 /* IJSVGTraitedColorStorage.h in Headers */,
|
||||
59EB762123905F7300F5AE63 /* IJSVGTransform.h in Headers */,
|
||||
59EB763F23905F7300F5AE63 /* IJSVGForeignObject.h in Headers */,
|
||||
59EB75F423905F7300F5AE63 /* IJSVGColor.h in Headers */,
|
||||
@@ -602,11 +686,10 @@
|
||||
59EB764123905F7300F5AE63 /* IJSVGImageLayer.h in Headers */,
|
||||
59EB75E023905F7300F5AE63 /* IJSVGStyleSheet.h in Headers */,
|
||||
59EB761423905F7300F5AE63 /* IJSVGImageRep.h in Headers */,
|
||||
59EB761223905F7300F5AE63 /* IJSVGRenderingStyle.h in Headers */,
|
||||
59EB761223905F7300F5AE63 /* IJSVGStyle.h in Headers */,
|
||||
59EB760E23905F7300F5AE63 /* IJSVGPath.h in Headers */,
|
||||
59EB75EA23905F7300F5AE63 /* IJSVGTransaction.h in Headers */,
|
||||
59EB75D723905F7300F5AE63 /* IJSVGGradientLayer.h in Headers */,
|
||||
59EB75F723905F7300F5AE63 /* IJSVGDef.h in Headers */,
|
||||
59EB760623905F7300F5AE63 /* IJSVGCommandHorizontalLine.h in Headers */,
|
||||
59EB762323905F7300F5AE63 /* IJSVGExporterPathInstruction.h in Headers */,
|
||||
59EB761023905F7300F5AE63 /* IJSVGLinearGradient.h in Headers */,
|
||||
@@ -617,13 +700,14 @@
|
||||
59EB75F023905F7300F5AE63 /* IJSVGStyleSheetSelectorRaw.h in Headers */,
|
||||
59EB761823905F7300F5AE63 /* IJSVGParser.h in Headers */,
|
||||
59EB761E23905F7300F5AE63 /* IJSVGGroupLayer.h in Headers */,
|
||||
59EB761D23905F7300F5AE63 /* IJSVGStyle.h in Headers */,
|
||||
59EB761D23905F7300F5AE63 /* IJSVGStyleSheetStyle.h in Headers */,
|
||||
5919E65723F47FF60051873A /* IJSVGUnitRect.h in Headers */,
|
||||
5919E65B23F480330051873A /* IJSVGUnitPoint.h in Headers */,
|
||||
591A3E4D25CC91F800AD45B7 /* IJSVGParsing.h in Headers */,
|
||||
59A24EBC23F480EA0090C374 /* IJSVGUnitSize.h in Headers */,
|
||||
59EB764523905F7300F5AE63 /* IJSVGExporter.h in Headers */,
|
||||
59F36508262F1ABB00BCE3FD /* IJSVGColorType.h in Headers */,
|
||||
595FD12F29EC56BA00666897 /* IJSVGUmbrella.h in Headers */,
|
||||
59F36508262F1ABB00BCE3FD /* IJSVGTraitedColor.h in Headers */,
|
||||
59E7CFAF23B148600077D599 /* IJSVGCommandParser.h in Headers */,
|
||||
59EB762823905F7300F5AE63 /* IJSVGCommandClose.h in Headers */,
|
||||
59EB75E423905F7300F5AE63 /* IJSVGGradientUnitLength.h in Headers */,
|
||||
@@ -631,9 +715,23 @@
|
||||
594A10DA248D7C90001A3181 /* NSImage+IJSVGAdditions.h in Headers */,
|
||||
59EB762D23905F7300F5AE63 /* IJSVGLayerTree.h in Headers */,
|
||||
59FDBF0027F3454800AF7038 /* IJSVGColorNode.h in Headers */,
|
||||
590AA091280DDDA3002BBE12 /* IJSVGFilterEffect.h in Headers */,
|
||||
590AA08D280DDD90002BBE12 /* IJSVGFilter.h in Headers */,
|
||||
59F38A63280ED99200804FE4 /* IJSVGBasicLayer.h in Headers */,
|
||||
595BA91C280EB29B00AD1C89 /* IJSVGFilterLayer.h in Headers */,
|
||||
590AA096280DE668002BBE12 /* IJSVGFilterEffectGaussianBlur.h in Headers */,
|
||||
590EB7A427F637EF0047CECF /* IJSVGTransformLayer.h in Headers */,
|
||||
59AC865A2810156B00CD5685 /* IJSVGThreadManager.h in Headers */,
|
||||
5978C46A280A241200D25296 /* IJSVGRootLayer.h in Headers */,
|
||||
59F9EAF82808BB5F00188ACB /* IJSVGViewBox.h in Headers */,
|
||||
5910A9AA284377D600BD1F03 /* IJSVGClipPath.h in Headers */,
|
||||
5926079F287D6C1000E93B09 /* IJSVGFeatureFlags.h in Headers */,
|
||||
59E6690D287D6C810085EDF5 /* IJSVGFeatureFlag.h in Headers */,
|
||||
5910A9A628427AD600BD1F03 /* IJSVGMask.h in Headers */,
|
||||
5919111E28C7F1160047791B /* IJSVGBitFlags.h in Headers */,
|
||||
59FE8E4428C7E70800AB38B3 /* IJSVGStop.h in Headers */,
|
||||
5955731F286C643900156047 /* IJSVGTileLayer.h in Headers */,
|
||||
59DB84E028C9F70000A9696A /* IJSVGBitFlags64.h in Headers */,
|
||||
59EB760B23905F7300F5AE63 /* IJSVGStyleSheetSelector.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -665,7 +763,8 @@
|
||||
594CF466238FF38E009B251B /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1220;
|
||||
BuildIndependentTargetsInParallel = YES;
|
||||
LastUpgradeCheck = 1520;
|
||||
ORGANIZATIONNAME = "Curtis Hard";
|
||||
TargetAttributes = {
|
||||
594CF46E238FF38E009B251B = {
|
||||
@@ -706,16 +805,23 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
592607A0287D6C1000E93B09 /* IJSVGFeatureFlags.m in Sources */,
|
||||
59FE8E4328C7E70800AB38B3 /* IJSVGStop.m in Sources */,
|
||||
59EB763123905F7300F5AE63 /* IJSVGText.m in Sources */,
|
||||
59A24EBD23F480EA0090C374 /* IJSVGUnitSize.m in Sources */,
|
||||
59EB760223905F7300F5AE63 /* IJSVGCommandVerticalLine.m in Sources */,
|
||||
59EB75FD23905F7300F5AE63 /* IJSVGPatternLayer.m in Sources */,
|
||||
59EB763923905F7300F5AE63 /* IJSVGCommandSmoothQuadraticCurve.m in Sources */,
|
||||
59EB75D823905F7300F5AE63 /* IJSVGStyleSheetRule.m in Sources */,
|
||||
590AA092280DDDA3002BBE12 /* IJSVGFilterEffect.m in Sources */,
|
||||
59AC865B2810156B00CD5685 /* IJSVGThreadManager.m in Sources */,
|
||||
59EB75FB23905F7300F5AE63 /* IJSVGPath.m in Sources */,
|
||||
59F36509262F1ABB00BCE3FD /* IJSVGColorType.m in Sources */,
|
||||
590AA097280DE668002BBE12 /* IJSVGFilterEffectGaussianBlur.m in Sources */,
|
||||
59F36509262F1ABB00BCE3FD /* IJSVGTraitedColor.m in Sources */,
|
||||
59EB760123905F7300F5AE63 /* IJSVGLayerTree.m in Sources */,
|
||||
59DB84E128C9F70000A9696A /* IJSVGBitFlags64.m in Sources */,
|
||||
59EB763A23905F7300F5AE63 /* IJSVGForeignObject.m in Sources */,
|
||||
59E6690E287D6C810085EDF5 /* IJSVGFeatureFlag.m in Sources */,
|
||||
59EB761123905F7300F5AE63 /* IJSVGCommand.m in Sources */,
|
||||
59EB760923905F7300F5AE63 /* IJSVGCommandCurve.m in Sources */,
|
||||
59EB763323905F7300F5AE63 /* IJSVGLinearGradient.m in Sources */,
|
||||
@@ -727,21 +833,27 @@
|
||||
59EB75E523905F7300F5AE63 /* IJSVGStrokeLayer.m in Sources */,
|
||||
59EB763223905F7300F5AE63 /* IJSVGView.m in Sources */,
|
||||
59EB763523905F7300F5AE63 /* IJSVGStyleSheetSelector.m in Sources */,
|
||||
590AA08E280DDD90002BBE12 /* IJSVGFilter.m in Sources */,
|
||||
59E7CFB023B148600077D599 /* IJSVGCommandParser.m in Sources */,
|
||||
5910A9AB284377D600BD1F03 /* IJSVGClipPath.m in Sources */,
|
||||
59EB760723905F7300F5AE63 /* IJSVGNode.m in Sources */,
|
||||
5919111F28C7F1160047791B /* IJSVGBitFlags.m in Sources */,
|
||||
5919E65C23F480330051873A /* IJSVGUnitPoint.m in Sources */,
|
||||
59EB75E923905F7300F5AE63 /* IJSVGStringAdditions.m in Sources */,
|
||||
59FDBF0127F3454800AF7038 /* IJSVGColorNode.m in Sources */,
|
||||
59557320286C643900156047 /* IJSVGTileLayer.m in Sources */,
|
||||
59EB761723905F7300F5AE63 /* IJSVGRadialGradient.m in Sources */,
|
||||
59EB75E223905F7300F5AE63 /* IJSVGColorList.m in Sources */,
|
||||
59EB75ED23905F7300F5AE63 /* IJSVGFontConverter.m in Sources */,
|
||||
59EB75E223905F7300F5AE63 /* IJSVGTraitedColorStorage.m in Sources */,
|
||||
595BA91D280EB29B00AD1C89 /* IJSVGFilterLayer.m in Sources */,
|
||||
59EB763C23905F7300F5AE63 /* IJSVGCommandEllipticalArc.m in Sources */,
|
||||
59EB75E723905F7300F5AE63 /* IJSVGImage.m in Sources */,
|
||||
59EB75E623905F7300F5AE63 /* IJSVGStyle.m in Sources */,
|
||||
59EB75E623905F7300F5AE63 /* IJSVGStyleSheetStyle.m in Sources */,
|
||||
59F38A64280ED99200804FE4 /* IJSVGBasicLayer.m in Sources */,
|
||||
59EB75EB23905F7300F5AE63 /* IJSVGShapeLayer.m in Sources */,
|
||||
59EB75F623905F7300F5AE63 /* IJSVGColor.m in Sources */,
|
||||
59EB75F323905F7300F5AE63 /* IJSVGGroupLayer.m in Sources */,
|
||||
591A3E4E25CC91F800AD45B7 /* IJSVGParsing.m in Sources */,
|
||||
5910A9A728427AD600BD1F03 /* IJSVGMask.m in Sources */,
|
||||
5919E65823F47FF60051873A /* IJSVGUnitRect.m in Sources */,
|
||||
5978C46B280A241200D25296 /* IJSVGRootLayer.m in Sources */,
|
||||
59EB762523905F7300F5AE63 /* IJSVGTransform.m in Sources */,
|
||||
@@ -753,14 +865,13 @@
|
||||
59EB761623905F7300F5AE63 /* IJSVGParser.m in Sources */,
|
||||
59EB75DD23905F7300F5AE63 /* IJSVGCommandQuadraticCurve.m in Sources */,
|
||||
59EB762423905F7300F5AE63 /* IJSVGTransaction.m in Sources */,
|
||||
59EB75DA23905F7300F5AE63 /* IJSVGDef.m in Sources */,
|
||||
59EB763723905F7300F5AE63 /* IJSVGCommandClose.m in Sources */,
|
||||
59F9EAF92808BB5F00188ACB /* IJSVGViewBox.m in Sources */,
|
||||
59EB764323905F7300F5AE63 /* IJSVGGradient.m in Sources */,
|
||||
59EB762A23905F7300F5AE63 /* IJSVGGradientUnitLength.m in Sources */,
|
||||
59EB764223905F7300F5AE63 /* IJSVGStyleSheet.m in Sources */,
|
||||
59EB764023905F7300F5AE63 /* IJSVGExporterPathInstruction.m in Sources */,
|
||||
59EB75FE23905F7300F5AE63 /* IJSVGRenderingStyle.m in Sources */,
|
||||
59EB75FE23905F7300F5AE63 /* IJSVGStyle.m in Sources */,
|
||||
59EB75F223905F7300F5AE63 /* IJSVGStyleSheetSelectorRaw.m in Sources */,
|
||||
590EB7A527F637EF0047CECF /* IJSVGTransformLayer.m in Sources */,
|
||||
59EB75EE23905F7300F5AE63 /* IJSVGImageRep.m in Sources */,
|
||||
@@ -812,9 +923,13 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEFINES_MODULE = YES;
|
||||
ENABLE_MODULE_VERIFIER = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
@@ -830,10 +945,14 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||
MODULEMAP_FILE = IJSVG.modulemap;
|
||||
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
|
||||
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14";
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_MODULE_NAME = IJSVG;
|
||||
SDKROOT = macosx;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@@ -875,9 +994,13 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEFINES_MODULE = YES;
|
||||
ENABLE_MODULE_VERIFIER = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_PREFIX_HEADER = "";
|
||||
@@ -887,9 +1010,13 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||
MODULEMAP_FILE = IJSVG.modulemap;
|
||||
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
|
||||
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_MODULE_NAME = IJSVG;
|
||||
SDKROOT = macosx;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@@ -899,13 +1026,14 @@
|
||||
594CF478238FF38E009B251B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_OBJC_ARC = NO;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 2;
|
||||
DEFINES_MODULE = NO;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 9KTR4W9XX6;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
@@ -917,6 +1045,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||
MARKETING_VERSION = 2.2.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.iconjar.ijsvg;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
@@ -927,13 +1056,14 @@
|
||||
594CF479238FF38E009B251B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_OBJC_ARC = NO;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 2;
|
||||
DEFINES_MODULE = NO;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 9KTR4W9XX6;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
@@ -945,6 +1075,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||
MARKETING_VERSION = 2.2.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.iconjar.ijsvg;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1250"
|
||||
LastUpgradeVersion = "1520"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGStringAdditions.h"
|
||||
#import "IJSVGUtils.h"
|
||||
#import <IJSVG/IJSVGStringAdditions.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
|
||||
@implementation NSString (IJSVGAdditions)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
return @[];
|
||||
}
|
||||
NSMutableArray<NSString*>* strings = nil;
|
||||
strings = [[[NSMutableArray alloc] init] autorelease];
|
||||
strings = [[NSMutableArray alloc] init];
|
||||
char* copy = strdup(chars);
|
||||
char* spt = NULL;
|
||||
char* ptr = strtok_r(copy, aChar, &spt);
|
||||
@@ -38,7 +38,7 @@
|
||||
const char* buffer = self.UTF8String;
|
||||
char currentChar;
|
||||
while((currentChar = *buffer++) ) {
|
||||
if (isalpha(currentChar)) {
|
||||
if(isalpha(currentChar)) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@
|
||||
const char* buffer = self.UTF8String;
|
||||
char currentChar;
|
||||
while((currentChar = *buffer++) ) {
|
||||
if (!isnumber(currentChar)) {
|
||||
if(!isnumber(currentChar)) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
// Copyright © 2020 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGImageRep.h"
|
||||
#import "NSImage+IJSVGAdditions.h"
|
||||
#import <IJSVG/IJSVGImageRep.h>
|
||||
#import <IJSVG/NSImage+IJSVGAdditions.h>
|
||||
|
||||
IJSVG* IJSVGGetFromNSImage(NSImage* image)
|
||||
{
|
||||
for (NSImageRep* rep in image.representations) {
|
||||
if ([rep isKindOfClass:IJSVGImageRep.class]) {
|
||||
if([rep isKindOfClass:IJSVGImageRep.class]) {
|
||||
return ((IJSVGImageRep*)rep).SVG;
|
||||
}
|
||||
}
|
||||
@@ -27,23 +27,23 @@ IJSVG* IJSVGGetFromNSImage(NSImage* image)
|
||||
NSBundle* bundle = NSBundle.mainBundle;
|
||||
NSString* str = nil;
|
||||
NSString* ext = imageName.pathExtension;
|
||||
if (ext == nil || ext.length == 0) {
|
||||
if(ext == nil || ext.length == 0) {
|
||||
ext = @"svg";
|
||||
}
|
||||
|
||||
if ((str = [bundle pathForResource:imageName.stringByDeletingPathExtension
|
||||
if((str = [bundle pathForResource:imageName.stringByDeletingPathExtension
|
||||
ofType:ext])
|
||||
!= nil) {
|
||||
|
||||
// work out if we can get the data
|
||||
NSData* data = [[[NSData alloc] initWithContentsOfFile:str] autorelease];
|
||||
if (data == nil) {
|
||||
NSData* data = [[NSData alloc] initWithContentsOfFile:str];
|
||||
if(data == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// grab the image rep
|
||||
IJSVGImageRep* rep = [[[IJSVGImageRep alloc] initWithData:data] autorelease];
|
||||
NSImage* image = [[[NSImage alloc] init] autorelease];
|
||||
IJSVGImageRep* rep = [[IJSVGImageRep alloc] initWithData:data];
|
||||
NSImage* image = [[NSImage alloc] init];
|
||||
[image addRepresentation:rep];
|
||||
return image;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGColor.h"
|
||||
#import "IJSVGUtils.h"
|
||||
#import "IJSVGStringAdditions.h"
|
||||
#import "IJSVGParsing.h"
|
||||
#import <IJSVG/IJSVGColor.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
#import <IJSVG/IJSVGStringAdditions.h>
|
||||
#import <IJSVG/IJSVGParsing.h>
|
||||
#import <IJSVG/IJSVGParser.h>
|
||||
|
||||
NSString* const IJSVGColorCurrentColorName = @"currentColor";
|
||||
|
||||
@@ -28,7 +29,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
|
||||
CGFloat s = saturation * ((lightness < 1.f) ? lightness : (2.f - lightness));
|
||||
CGFloat brightness = (lightness + s) * .5f;
|
||||
if (s != 0.f) {
|
||||
if(s != 0.f) {
|
||||
s = (2.f * s) / (lightness + s);
|
||||
}
|
||||
CGFloat* floats = (CGFloat*)malloc(3 * sizeof(CGFloat));
|
||||
@@ -51,7 +52,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
+ (NSColor*)computeColorSpace:(NSColor*)color
|
||||
{
|
||||
NSColorSpace* space = [self defaultColorSpace];
|
||||
if (color.colorSpace != space) {
|
||||
if(color.colorSpace != space) {
|
||||
color = [color colorUsingColorSpace:space];
|
||||
}
|
||||
return color;
|
||||
@@ -61,7 +62,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_colorTree = [@{
|
||||
_colorTree = @{
|
||||
@"aliceblue" : @(0xf0f8ff),
|
||||
@"antiquewhite" : @(0xfaebd7),
|
||||
@"aqua" : @(0x00ffff),
|
||||
@@ -207,13 +208,13 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
@"whitesmoke" : @(0xf5f5f5),
|
||||
@"yellow" : @(0xffff00),
|
||||
@"yellowgreen" : @(0x9acd32)
|
||||
} retain];
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
+ (NSColor*)computeColor:(id)colour
|
||||
{
|
||||
if ([colour isKindOfClass:[NSColor class]])
|
||||
if([colour isKindOfClass:[NSColor class]])
|
||||
return colour;
|
||||
return nil;
|
||||
}
|
||||
@@ -246,8 +247,9 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
|
||||
+ (BOOL)isNoneOrTransparent:(NSString*)string
|
||||
{
|
||||
const char* str = string.lowercaseString.UTF8String;
|
||||
return strcmp(str, "none") == 0 || strcmp(str, "transparent") == 0;
|
||||
const char* str = string.UTF8String;
|
||||
return IJSVGCharBufferCaseInsensitiveCompare(str, "none") == YES ||
|
||||
IJSVGCharBufferCaseInsensitiveCompare(str, "transparent") == YES;
|
||||
}
|
||||
|
||||
+ (NSColor*)colorFromString:(NSString*)string
|
||||
@@ -263,13 +265,14 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
}
|
||||
|
||||
char* str = IJSVGTimmedCharBufferCreate(oString);
|
||||
if (IJSVGCharBufferIsHEX(str) == YES) {
|
||||
if(IJSVGCharBufferIsHEX(str) == YES) {
|
||||
string = [NSString stringWithUTF8String:str];
|
||||
(void)free(str), str = NULL;
|
||||
return [self.class colorFromHEXString:string];
|
||||
}
|
||||
|
||||
// is it RGB?
|
||||
if (IJSVGCharBufferHasPrefix(str, "rgb") == YES) {
|
||||
if(IJSVGCharBufferHasPrefix(str, "rgb") == YES) {
|
||||
NSUInteger count = 0;
|
||||
IJSVGParsingStringMethod** methods = NULL;
|
||||
methods = IJSVGParsingMethodParseString(str, &count);
|
||||
@@ -287,11 +290,21 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Make sure we have actual floats within the parameters
|
||||
NSInteger floatCount = 0;
|
||||
CGFloat *params = [IJSVGUtils scanFloatsFromCString:method->parameters
|
||||
size:&floatCount];
|
||||
(void)free(params), params = NULL;
|
||||
if(floatCount < 3) {
|
||||
return [self computeColorSpace:NSColor.blackColor];
|
||||
}
|
||||
|
||||
// Make sure the floats are not negative
|
||||
// parse the parameters
|
||||
NSString* parameters = [NSString stringWithUTF8String:method->parameters];
|
||||
NSArray* parts = [parameters ijsvg_componentsSeparatedByChars:","];
|
||||
NSString* alpha = @"100%";
|
||||
if (parts.count == 4) {
|
||||
if(parts.count == 4) {
|
||||
alpha = parts[3];
|
||||
}
|
||||
|
||||
@@ -304,12 +317,12 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
}
|
||||
|
||||
// is it HSL?
|
||||
if (IJSVGCharBufferHasPrefix(str, "hsl")) {
|
||||
if(IJSVGCharBufferHasPrefix(str, "hsl")) {
|
||||
NSInteger count = 0;
|
||||
CGFloat* params = [IJSVGUtils scanFloatsFromCString:str
|
||||
size:&count];
|
||||
CGFloat alpha = 1;
|
||||
if (count == 4) {
|
||||
if(count == 4) {
|
||||
alpha = params[3];
|
||||
}
|
||||
|
||||
@@ -330,8 +343,8 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
}
|
||||
|
||||
// is simply a clear color, dont fill
|
||||
if (strcmp(str, "none") == 0 ||
|
||||
strcmp(str, "transparent") == 0) {
|
||||
if(IJSVGCharBufferCompare(str, "none") == YES ||
|
||||
IJSVGCharBufferCompare(str, "transparent") == YES) {
|
||||
(void)free(str), str = NULL;
|
||||
return nil;
|
||||
}
|
||||
@@ -345,7 +358,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
{
|
||||
NSNumber* hex = nil;
|
||||
name = [name.lowercaseString stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
|
||||
if ((hex = _colorTree[name]) == nil) {
|
||||
if((hex = _colorTree[name]) == nil) {
|
||||
return nil;
|
||||
}
|
||||
return [self.class colorFromHEXInteger:hex.integerValue];
|
||||
@@ -374,33 +387,33 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
BOOL allowRRGGBBAA = (options & IJSVGColorStringOptionAllowRRGGBBAA) != 0;
|
||||
|
||||
// jsut return none
|
||||
if (alpha == 0 && forceHex == NO) {
|
||||
return @"none";
|
||||
if(alpha == 0 && forceHex == NO) {
|
||||
return IJSVGStringNone;
|
||||
}
|
||||
|
||||
// always return hex unless criteria is met
|
||||
if (forceHex == YES || allowRRGGBBAA == YES || alpha == 100 || (red == 0 && green == 0 && blue == 0 && alpha == 0) || (red == 255 && green == 255 && blue == 255 && alpha == 100)) {
|
||||
if(forceHex == YES || allowRRGGBBAA == YES || alpha == 100 || (red == 0 && green == 0 && blue == 0 && alpha == 0) || (red == 255 && green == 255 && blue == 255 && alpha == 100)) {
|
||||
|
||||
// we need to make sure the last 2 chars
|
||||
// are the same or we cant enable shorthand
|
||||
if (allowRRGGBBAA == YES) {
|
||||
if(allowRRGGBBAA == YES) {
|
||||
NSString* alphaHexString = [NSString stringWithFormat:@"%02X",
|
||||
(int)(color.alphaComponent * 0xFF)];
|
||||
if ([alphaHexString characterAtIndex:0] !=
|
||||
if([alphaHexString characterAtIndex:0] !=
|
||||
[alphaHexString characterAtIndex:1]) {
|
||||
allowShortHand = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (allowShortHand == YES) {
|
||||
if(allowShortHand == YES) {
|
||||
NSString* r = [NSString stringWithFormat:@"%02X", red];
|
||||
NSString* g = [NSString stringWithFormat:@"%02X", green];
|
||||
NSString* b = [NSString stringWithFormat:@"%02X", blue];
|
||||
if ([r characterAtIndex:0] == [r characterAtIndex:1] &&
|
||||
if([r characterAtIndex:0] == [r characterAtIndex:1] &&
|
||||
[g characterAtIndex:0] == [g characterAtIndex:1] &&
|
||||
[b characterAtIndex:0] == [b characterAtIndex:1]) {
|
||||
// allow shorthand alpha
|
||||
if (allowRRGGBBAA == YES && alpha != 100) {
|
||||
if(allowRRGGBBAA == YES && alpha != 100) {
|
||||
NSString* a = [NSString stringWithFormat:@"%02X",
|
||||
(int)(color.alphaComponent * 0xFF)];
|
||||
return [NSString stringWithFormat:@"#%c%c%c%c",
|
||||
@@ -411,7 +424,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
[g characterAtIndex:0], [b characterAtIndex:0]];
|
||||
}
|
||||
}
|
||||
if (allowRRGGBBAA == YES && alpha != 100) {
|
||||
if(allowRRGGBBAA == YES && alpha != 100) {
|
||||
return [NSString stringWithFormat:@"#%02X%02X%02X%02X", red, green,
|
||||
blue, (int)(color.alphaComponent * 0xFF)];
|
||||
}
|
||||
@@ -761,7 +774,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
+ (NSColor*)colorFromHEXInteger:(NSInteger)hex
|
||||
{
|
||||
CGFloat alpha = 1.f;
|
||||
if ([self HEXContainsAlphaComponent:hex] == YES) {
|
||||
if([self HEXContainsAlphaComponent:hex] == YES) {
|
||||
alpha = (hex & 0xFF) / 255.f;
|
||||
hex = hex >> 8;
|
||||
}
|
||||
@@ -793,7 +806,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
|
||||
char* str = (char*)string.UTF8String;
|
||||
size_t length = strlen(str);
|
||||
if (length == 0 || IJSVGCharBufferIsHEX(str) == NO) {
|
||||
if(length == 0 || IJSVGCharBufferIsHEX(str) == NO) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -806,7 +819,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
unsigned long hex;
|
||||
// we need to work out if its shorthand
|
||||
// if it is, the length needs to be length*2
|
||||
if (length == 3 || length == 4) {
|
||||
if(length == 3 || length == 4) {
|
||||
char* chars = NULL;
|
||||
chars = (char*)calloc(sizeof(char),length*2+1);
|
||||
for(int i = 0; i < length; i++) {
|
||||
@@ -819,7 +832,7 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
}
|
||||
|
||||
// now convert rest to hex
|
||||
if (containsAlphaComponent != nil) {
|
||||
if(containsAlphaComponent != nil) {
|
||||
*containsAlphaComponent = [self HEXContainsAlphaComponent:hex];
|
||||
}
|
||||
return [self colorFromHEXInteger:hex];
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
//
|
||||
// IJSVGColorList.h
|
||||
// IconJar
|
||||
//
|
||||
// Created by Curtis Hard on 07/07/2019.
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGColor.h>
|
||||
#import <IJSVG/IJSVGColorType.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGColorList : NSObject <NSCopying> {
|
||||
|
||||
@private
|
||||
NSMutableDictionary<NSColor*, NSColor*>* _replacementColorTree;
|
||||
NSMutableSet<IJSVGColorType*>* _colors;
|
||||
}
|
||||
|
||||
@property (nonatomic, assign, readonly) NSUInteger count;
|
||||
|
||||
- (NSColor*)proposedColorForColor:(NSColor*)color;
|
||||
- (void)removeAllReplacementColors;
|
||||
- (void)removeReplacementColor:(NSColor*)color;
|
||||
- (void)setReplacementColor:(NSColor*)newColor
|
||||
forColor:(NSColor*)color;
|
||||
- (void)setReplacementColors:(NSDictionary<NSColor*, NSColor*>*)colors
|
||||
clearExistingColors:(BOOL)clearExistingColors;
|
||||
|
||||
- (void)addColorsFromList:(IJSVGColorList*)sheet;
|
||||
- (NSSet<IJSVGColorType*>*)colors;
|
||||
- (void)addColor:(IJSVGColorType*)color;
|
||||
- (NSDictionary<NSColor*, NSColor*>*)replacementColors;
|
||||
|
||||
@end
|
||||
@@ -1,136 +0,0 @@
|
||||
//
|
||||
// IJSVGColorList.m
|
||||
// IconJar
|
||||
//
|
||||
// Created by Curtis Hard on 07/07/2019.
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGColorList.h"
|
||||
|
||||
@implementation IJSVGColorList
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_replacementColorTree release]), _replacementColorTree = nil;
|
||||
(void)([_colors release]), _colors = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
_replacementColorTree = [[NSMutableDictionary alloc] init];
|
||||
_colors = [[NSMutableSet alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
IJSVGColorList* sheet = [[self.class alloc] init];
|
||||
[sheet setReplacementColors:[_replacementColorTree.copy autorelease]
|
||||
clearExistingColors:YES];
|
||||
return sheet;
|
||||
}
|
||||
|
||||
- (NSColor*)proposedColorForColor:(NSColor*)color
|
||||
{
|
||||
// nothing found, just return color
|
||||
if (_replacementColorTree == nil || _replacementColorTree.count == 0) {
|
||||
return color;
|
||||
}
|
||||
|
||||
// check the mappings
|
||||
NSColor* found = nil;
|
||||
color = [IJSVGColor computeColorSpace:color];
|
||||
if ((found = _replacementColorTree[color]) != nil) {
|
||||
return found;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
- (void)_invalidateColorTree
|
||||
{
|
||||
(void)([_replacementColorTree release]), _replacementColorTree = nil;
|
||||
_replacementColorTree = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
|
||||
- (void)removeAllReplacementColors
|
||||
{
|
||||
[self _invalidateColorTree];
|
||||
}
|
||||
|
||||
- (void)removeReplacementColor:(NSColor*)color
|
||||
{
|
||||
if (_replacementColorTree == nil) {
|
||||
return;
|
||||
}
|
||||
[_replacementColorTree removeObjectForKey:[IJSVGColor computeColorSpace:color]];
|
||||
}
|
||||
|
||||
- (void)setReplacementColor:(NSColor*)newColor
|
||||
forColor:(NSColor*)color
|
||||
{
|
||||
color = [IJSVGColor computeColorSpace:color];
|
||||
newColor = [IJSVGColor computeColorSpace:newColor];
|
||||
_replacementColorTree[color] = newColor;
|
||||
}
|
||||
|
||||
- (void)setReplacementColors:(NSDictionary<NSColor*, NSColor*>*)colors
|
||||
clearExistingColors:(BOOL)clearExistingColors
|
||||
{
|
||||
if (clearExistingColors == YES) {
|
||||
[self _invalidateColorTree];
|
||||
}
|
||||
for (NSColor* oldColor in colors) {
|
||||
[self setReplacementColor:colors[oldColor]
|
||||
forColor:oldColor];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSSet<IJSVGColorType*>*)colors
|
||||
{
|
||||
return [NSSet setWithSet:_colors];
|
||||
}
|
||||
|
||||
- (void)addColorsFromList:(IJSVGColorList*)sheet
|
||||
{
|
||||
for(IJSVGColorType* color in sheet.colors) {
|
||||
[self addColor:color];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addColor:(IJSVGColorType*)color
|
||||
{
|
||||
// we just need to update its bit mask
|
||||
if([_colors containsObject:color] == YES) {
|
||||
void (^handler)(IJSVGColorType * _Nonnull obj, BOOL * _Nonnull stop) =
|
||||
^(IJSVGColorType * _Nonnull obj, BOOL * _Nonnull stop) {
|
||||
if([obj isEqual:color] == YES) {
|
||||
obj.flags |= color.flags;
|
||||
*stop = YES;
|
||||
}
|
||||
};
|
||||
[_colors enumerateObjectsUsingBlock:handler];
|
||||
return;
|
||||
}
|
||||
[_colors addObject:color];
|
||||
}
|
||||
|
||||
- (NSDictionary<NSColor*,NSColor*>*)replacementColors
|
||||
{
|
||||
return _replacementColorTree;
|
||||
}
|
||||
|
||||
- (void)removeColor:(IJSVGColorType*)color
|
||||
{
|
||||
[_colors removeObject:color];
|
||||
}
|
||||
|
||||
- (NSUInteger)count
|
||||
{
|
||||
return _colors.count;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -9,22 +9,24 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
typedef NS_OPTIONS(NSInteger, IJSVGColorTypeFlags) {
|
||||
IJSVGColorTypeNone = 0,
|
||||
IJSVGColorTypeFlagUnknown = 1 << 0,
|
||||
IJSVGColorTypeFlagFill = 1 << 1,
|
||||
IJSVGColorTypeFlagStroke = 1 << 2,
|
||||
IJSVGColorTypeFlagStop = 1 << 3
|
||||
typedef NS_OPTIONS(NSInteger, IJSVGColorUsageTraits) {
|
||||
IJSVGColorUsageTraitNone = 0,
|
||||
IJSVGColorUsageTraitUnknown = 1 << 0,
|
||||
IJSVGColorUsageTraitFill = 1 << 1,
|
||||
IJSVGColorUsageTraitStroke = 1 << 2,
|
||||
IJSVGColorUsageTraitGradientStop = 1 << 3,
|
||||
IJSVGColorUsageTraitAll = IJSVGColorUsageTraitFill | IJSVGColorUsageTraitGradientStop |
|
||||
IJSVGColorUsageTraitStroke
|
||||
};
|
||||
|
||||
@interface IJSVGColorType : NSObject {
|
||||
@interface IJSVGTraitedColor : NSObject {
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) NSColor* color;
|
||||
@property (nonatomic, assign) IJSVGColorTypeFlags flags;
|
||||
@property (nonatomic, strong) NSColor* color;
|
||||
@property (nonatomic, assign) IJSVGColorUsageTraits traits;
|
||||
|
||||
+ (IJSVGColorType*)typeWithColor:(NSColor*)color
|
||||
flags:(IJSVGColorTypeFlags)mask;
|
||||
+ (IJSVGTraitedColor*)typeWithColor:(NSColor*)color
|
||||
traits:(IJSVGColorUsageTraits)mask;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
//
|
||||
// IJSVGColorType.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 20/04/2021.
|
||||
// Copyright © 2021 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGColorType.h"
|
||||
|
||||
@implementation IJSVGColorType
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)[_color release], _color = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
+ (IJSVGColorType*)typeWithColor:(NSColor*)color
|
||||
flags:(IJSVGColorTypeFlags)mask
|
||||
{
|
||||
IJSVGColorType* type = [[[self alloc] init] autorelease];
|
||||
type.color = color;
|
||||
type.flags = mask;
|
||||
return type;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if([object isKindOfClass:IJSVGColorType.class] == NO) {
|
||||
return NO;
|
||||
}
|
||||
return [self.color isEqual:((IJSVGColorType*)object).color];
|
||||
}
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
return self.color.hash;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// IJSVGColorType.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 20/04/2021.
|
||||
// Copyright © 2021 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
typedef NS_OPTIONS(NSInteger, IJSVGColorUsageTraits) {
|
||||
IJSVGColorUsageTraitNone = 0,
|
||||
IJSVGColorUsageTraitUnknown = 1 << 0,
|
||||
IJSVGColorUsageTraitFill = 1 << 1,
|
||||
IJSVGColorUsageTraitStroke = 1 << 2,
|
||||
IJSVGColorUsageTraitGradientStop = 1 << 3,
|
||||
IJSVGColorUsageTraitAll = IJSVGColorUsageTraitFill | IJSVGColorUsageTraitGradientStop |
|
||||
IJSVGColorUsageTraitStroke
|
||||
};
|
||||
|
||||
@interface IJSVGTraitedColor : NSObject {
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) NSColor* color;
|
||||
@property (nonatomic, assign) IJSVGColorUsageTraits traits;
|
||||
|
||||
+ (IJSVGTraitedColor*)colorWithColor:(NSColor*)color
|
||||
traits:(IJSVGColorUsageTraits)mask;
|
||||
|
||||
- (void)addTraits:(IJSVGColorUsageTraits)traits;
|
||||
- (void)removeTraits:(IJSVGColorUsageTraits)traits;
|
||||
- (BOOL)matchesTraits:(IJSVGColorUsageTraits)traits;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// IJSVGColorType.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 20/04/2021.
|
||||
// Copyright © 2021 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGTraitedColor.h>
|
||||
#import <IJSVG/IJSVGColor.h>
|
||||
|
||||
@implementation IJSVGTraitedColor
|
||||
|
||||
+ (IJSVGTraitedColor*)colorWithColor:(NSColor*)color
|
||||
traits:(IJSVGColorUsageTraits)traits
|
||||
{
|
||||
IJSVGTraitedColor* type = [[self alloc] init];
|
||||
type.color = color;
|
||||
type.traits = traits;
|
||||
return type;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if((self = [super init]) != nil) {
|
||||
_traits = IJSVGColorUsageTraitNone;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if([object isKindOfClass:IJSVGTraitedColor.class] == NO) {
|
||||
return NO;
|
||||
}
|
||||
return [self.color isEqual:((IJSVGTraitedColor*)object).color];
|
||||
}
|
||||
|
||||
- (void)setColor:(NSColor *)color
|
||||
{
|
||||
_color = [IJSVGColor computeColorSpace:color];
|
||||
}
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
return self.color.hash;
|
||||
}
|
||||
|
||||
- (void)addTraits:(IJSVGColorUsageTraits)traits
|
||||
{
|
||||
_traits |= traits;
|
||||
}
|
||||
|
||||
- (void)removeTraits:(IJSVGColorUsageTraits)traits
|
||||
{
|
||||
_traits = _traits & ~traits;
|
||||
}
|
||||
|
||||
- (BOOL)matchesTraits:(IJSVGColorUsageTraits)traits
|
||||
{
|
||||
return (self.traits & traits) == traits;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// IJSVGColorList.h
|
||||
// IconJar
|
||||
//
|
||||
// Created by Curtis Hard on 07/07/2019.
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGColor.h>
|
||||
#import <IJSVG/IJSVGTraitedColor.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGReplacementColor : IJSVGTraitedColor
|
||||
|
||||
@property (nonatomic, strong) NSColor* replacementColor;
|
||||
|
||||
@end
|
||||
|
||||
@interface IJSVGTraitedColorStorage : NSObject {
|
||||
|
||||
@private
|
||||
NSMutableArray<IJSVGReplacementColor*>* _replacementColors;
|
||||
NSMutableSet<IJSVGTraitedColor*>* _colors;
|
||||
IJSVGColorUsageTraits _traits;
|
||||
IJSVGColorUsageTraits _replacementTraits;
|
||||
}
|
||||
|
||||
@property (nonatomic, readonly) NSUInteger count;
|
||||
@property (nonatomic, readonly) NSSet<IJSVGTraitedColor*>* colors;
|
||||
@property (nonatomic, readonly) NSUInteger replacedColorCount;
|
||||
|
||||
- (void)addTraits:(IJSVGColorUsageTraits)traits;
|
||||
- (void)addColor:(IJSVGTraitedColor*)color;
|
||||
- (void)replaceColor:(NSColor*)replaceColor
|
||||
withColor:(NSColor*)withColor
|
||||
traits:(IJSVGColorUsageTraits)traits;
|
||||
- (void)unionColorStorage:(IJSVGTraitedColorStorage*)colorList;
|
||||
- (NSColor*)colorForColor:(NSColor*)color
|
||||
matchingTraits:(IJSVGColorUsageTraits)traits;
|
||||
- (BOOL)matchesReplacementTraits:(IJSVGColorUsageTraits)traits;
|
||||
- (BOOL)matchesTraits:(IJSVGColorUsageTraits)traits;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,146 @@
|
||||
//
|
||||
// IJSVGColorList.m
|
||||
// IconJar
|
||||
//
|
||||
// Created by Curtis Hard on 07/07/2019.
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGTraitedColorStorage.h>
|
||||
|
||||
@implementation IJSVGReplacementColor
|
||||
|
||||
- (void)setReplacementColor:(NSColor*)replacementColor
|
||||
{
|
||||
_replacementColor = [IJSVGColor computeColorSpace:replacementColor];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation IJSVGTraitedColorStorage
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if((self = [super init]) != nil) {
|
||||
_replacementColors = [[NSMutableArray alloc] init];
|
||||
_colors = [[NSMutableSet alloc] init];
|
||||
_replacementTraits = IJSVGColorUsageTraitNone;
|
||||
_traits = IJSVGColorUsageTraitNone;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)addColor:(IJSVGTraitedColor*)color
|
||||
{
|
||||
if([_colors containsObject:color] == YES) {
|
||||
void (^handler)(IJSVGTraitedColor * _Nonnull obj, BOOL * _Nonnull stop) =
|
||||
^(IJSVGTraitedColor * _Nonnull obj, BOOL * _Nonnull stop) {
|
||||
if([obj isEqual:color] == YES) {
|
||||
[obj addTraits:color.traits];
|
||||
*stop = YES;
|
||||
}
|
||||
};
|
||||
[_colors enumerateObjectsUsingBlock:handler];
|
||||
return;
|
||||
}
|
||||
_traits |= color.traits;
|
||||
[_colors addObject:color];
|
||||
}
|
||||
|
||||
- (void)addTraits:(IJSVGColorUsageTraits)traits
|
||||
{
|
||||
for(IJSVGTraitedColor* color in _colors) {
|
||||
[color addTraits:traits];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)replaceColor:(NSColor*)replaceColor
|
||||
withColor:(NSColor*)withColor
|
||||
traits:(IJSVGColorUsageTraits)traits
|
||||
{
|
||||
replaceColor = [IJSVGColor computeColorSpace:replaceColor];
|
||||
withColor = [IJSVGColor computeColorSpace:withColor];
|
||||
IJSVGReplacementColor* repColor = [self replacementColorForColor:replaceColor
|
||||
withColor:withColor];
|
||||
if(repColor == nil) {
|
||||
repColor = [[IJSVGReplacementColor alloc] init];
|
||||
repColor.color = replaceColor;
|
||||
repColor.replacementColor = withColor;
|
||||
[_replacementColors addObject:repColor];
|
||||
}
|
||||
_replacementTraits |= traits;
|
||||
[repColor addTraits:traits];
|
||||
}
|
||||
|
||||
- (IJSVGReplacementColor*)replacementColorForColor:(NSColor*)replacementColor
|
||||
withColor:(NSColor*)withColor
|
||||
{
|
||||
for(IJSVGReplacementColor* color in _replacementColors) {
|
||||
if([color.color isEqual:color] == YES &&
|
||||
[color.replacementColor isEqual:withColor] == YES) {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (IJSVGReplacementColor*)replacementColorForColor:(NSColor*)color
|
||||
matchingTraits:(IJSVGColorUsageTraits)traits
|
||||
{
|
||||
for(IJSVGReplacementColor* replacementColor in _replacementColors) {
|
||||
if([replacementColor.color isEqual:color] &&
|
||||
[replacementColor matchesTraits:traits] == YES) {
|
||||
return replacementColor;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSColor*)colorForColor:(NSColor*)color
|
||||
matchingTraits:(IJSVGColorUsageTraits)traits
|
||||
{
|
||||
if([self matchesReplacementTraits:traits] == NO) {
|
||||
return nil;
|
||||
}
|
||||
color = [IJSVGColor computeColorSpace:color];
|
||||
IJSVGReplacementColor* repColor = nil;
|
||||
if((repColor = [self replacementColorForColor:color
|
||||
matchingTraits:traits]) != nil) {
|
||||
return repColor.replacementColor;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)unionColorStorage:(IJSVGTraitedColorStorage*)colorList
|
||||
{
|
||||
for(IJSVGTraitedColor* traitedColor in colorList.colors) {
|
||||
[self addColor:traitedColor];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)matchesTraits:(IJSVGColorUsageTraits)traits
|
||||
{
|
||||
return (_traits & traits) == traits;
|
||||
}
|
||||
|
||||
- (BOOL)matchesReplacementTraits:(IJSVGColorUsageTraits)traits
|
||||
{
|
||||
return (_replacementTraits & traits) == traits;
|
||||
}
|
||||
|
||||
- (NSUInteger)replacedColorCount
|
||||
{
|
||||
return _replacementColors.count;
|
||||
}
|
||||
|
||||
- (NSUInteger)count
|
||||
{
|
||||
return _colors.count;
|
||||
}
|
||||
|
||||
- (NSSet<IJSVGTraitedColor*>*)colors
|
||||
{
|
||||
return _colors;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -26,7 +26,7 @@ typedef NS_ENUM(NSInteger, IJSVGCommandType) {
|
||||
@property (nonatomic, assign) CGFloat* parameters;
|
||||
@property (nonatomic, assign) NSInteger parameterCount;
|
||||
@property (nonatomic, assign) IJSVGCommandType type;
|
||||
@property (nonatomic, retain) NSArray<IJSVGCommand*>* subCommands;
|
||||
@property (nonatomic, strong) NSArray<IJSVGCommand*>* subCommands;
|
||||
@property (nonatomic, assign) IJSVGCommand* previousCommand;
|
||||
@property (nonatomic, assign) BOOL isSubCommand;
|
||||
|
||||
|
||||
@@ -6,19 +6,19 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommand.h"
|
||||
#import "IJSVGUtils.h"
|
||||
|
||||
#import "IJSVGCommandClose.h"
|
||||
#import "IJSVGCommandCurve.h"
|
||||
#import "IJSVGCommandEllipticalArc.h"
|
||||
#import "IJSVGCommandHorizontalLine.h"
|
||||
#import "IJSVGCommandLineTo.h"
|
||||
#import "IJSVGCommandMove.h"
|
||||
#import "IJSVGCommandQuadraticCurve.h"
|
||||
#import "IJSVGCommandSmoothCurve.h"
|
||||
#import "IJSVGCommandSmoothQuadraticCurve.h"
|
||||
#import "IJSVGCommandVerticalLine.h"
|
||||
#import <IJSVG/IJSVGCommand.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
#import <IJSVG/IJSVGCommandClose.h>
|
||||
#import <IJSVG/IJSVGCommandCurve.h>
|
||||
#import <IJSVG/IJSVGCommandEllipticalArc.h>
|
||||
#import <IJSVG/IJSVGCommandHorizontalLine.h>
|
||||
#import <IJSVG/IJSVGCommandLineTo.h>
|
||||
#import <IJSVG/IJSVGCommandMove.h>
|
||||
#import <IJSVG/IJSVGCommandQuadraticCurve.h>
|
||||
#import <IJSVG/IJSVGCommandSmoothCurve.h>
|
||||
#import <IJSVG/IJSVGCommandSmoothQuadraticCurve.h>
|
||||
#import <IJSVG/IJSVGCommandVerticalLine.h>
|
||||
#import <IJSVG/IJSVGThreadManager.h>
|
||||
|
||||
@implementation IJSVGCommand
|
||||
|
||||
@@ -112,28 +112,34 @@
|
||||
|
||||
+ (NSArray<IJSVGCommand*>*)commandsForDataCharacters:(const char*)buffer
|
||||
{
|
||||
IJSVGPathDataStream* stream = IJSVGPathDataStreamCreateDefault();
|
||||
IJSVGThreadManager* manager = IJSVGThreadManager.currentManager;
|
||||
NSArray<IJSVGCommand*>* commands = [self commandsForDataCharacters:buffer
|
||||
dataStream:stream];
|
||||
IJSVGPathDataStreamRelease(stream);
|
||||
dataStream:manager.pathDataStream];
|
||||
return commands;
|
||||
}
|
||||
|
||||
+ (NSArray<IJSVGCommand*>*)commandsForDataCharacters:(const char*)buffer
|
||||
+ (NSArray<IJSVGCommand*>*)commandsForDataCharacters:(const char*)unsafeBuffer
|
||||
dataStream:(IJSVGPathDataStream*)dataStream
|
||||
{
|
||||
NSMutableArray<IJSVGCommand*>* commands = [[[NSMutableArray alloc] init] autorelease];
|
||||
NSUInteger len = strlen(buffer);
|
||||
NSMutableArray<IJSVGCommand*>* commands = [[NSMutableArray alloc] init];
|
||||
NSUInteger len = strlen(unsafeBuffer);
|
||||
NSUInteger lastIndex = len - 1;
|
||||
|
||||
// we need to trim the buffer first as any given string given to us
|
||||
// could be unsafe and have random whitespace at the extremes.
|
||||
size_t bufferLength = sizeof(char)*(len + 1);
|
||||
char* buffer = (char*)malloc(bufferLength);
|
||||
memcpy(buffer, unsafeBuffer, bufferLength);
|
||||
IJSVGTrimCharBuffer(buffer);
|
||||
|
||||
// make sure we plus 1 for the null byte
|
||||
char* charBuffer = (char*)malloc(sizeof(char)*(len + 1));
|
||||
char* charBuffer = (char*)malloc(bufferLength);
|
||||
NSInteger start = 0;
|
||||
for (NSInteger i = 0; i < len; i++) {
|
||||
for (NSInteger i = start; i < len; i++) {
|
||||
char nextChar = buffer[i + 1];
|
||||
BOOL atEnd = i == lastIndex;
|
||||
BOOL isStartCommand = IJSVGIsLegalCommandCharacter(nextChar);
|
||||
if (isStartCommand == YES || atEnd == YES) {
|
||||
if(isStartCommand == YES || atEnd == YES) {
|
||||
|
||||
// copy memory from current buffer
|
||||
NSInteger index = ((i + 1) - start);
|
||||
@@ -151,17 +157,27 @@
|
||||
|
||||
// previous command is actual subcommand
|
||||
Class commandClass = [IJSVGCommand commandClassForCommandChar:commandString[0]];
|
||||
IJSVGCommand* command = nil;
|
||||
command = (IJSVGCommand*)[[[commandClass alloc] initWithCommandStringBuffer:commandString
|
||||
dataStream:dataStream] autorelease];
|
||||
|
||||
[commands addObject:command];
|
||||
if(commandClass != nil) {
|
||||
IJSVGCommand* command = nil;
|
||||
command = (IJSVGCommand*)[[commandClass alloc] initWithCommandStringBuffer:commandString
|
||||
dataStream:dataStream];
|
||||
|
||||
[commands addObject:command];
|
||||
}
|
||||
#if DEBUG
|
||||
else {
|
||||
// if we get here then the command buffer is invalid, nothing we can
|
||||
// do about it, just invalid data.
|
||||
NSLog(@"\"%s\" is not a valid command instruction set", commandString);
|
||||
}
|
||||
#endif
|
||||
|
||||
// free the memory as at this point, we are done with it
|
||||
(void)free(commandString), commandString = NULL;
|
||||
}
|
||||
}
|
||||
(void)free(charBuffer), charBuffer = NULL;
|
||||
(void)free(buffer), buffer = NULL;
|
||||
return commands;
|
||||
}
|
||||
|
||||
@@ -170,7 +186,7 @@
|
||||
bounds:(CGRect)bounds
|
||||
{
|
||||
NSMutableArray<IJSVGCommand*>* newCommands = nil;
|
||||
newCommands = [[[NSMutableArray alloc] initWithCapacity:commands.count] autorelease];
|
||||
newCommands = [[NSMutableArray alloc] initWithCapacity:commands.count];
|
||||
for(IJSVGCommand* command in commands) {
|
||||
IJSVGCommand* nCommand = [command commandByConvertingToUnits:unitType
|
||||
boundingBox:bounds];
|
||||
@@ -181,17 +197,15 @@
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_subCommands release]), _subCommands = nil;
|
||||
if (_parameters) {
|
||||
if(_parameters) {
|
||||
(void)(free(_parameters)), _parameters = nil;
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)initWithCommandStringBuffer:(const char*)str
|
||||
dataStream:(IJSVGPathDataStream*)dataStream
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
if((self = [super init]) != nil) {
|
||||
// work out the basics
|
||||
_currentIndex = 0;
|
||||
_command = str[0];
|
||||
@@ -202,15 +216,15 @@
|
||||
_parameters = IJSVGParsePathDataStreamSequence(str, strlen(str),
|
||||
dataStream, sequence, paramCount, &sets);
|
||||
|
||||
if (sets <= 1) {
|
||||
if(sets <= 1) {
|
||||
CGFloat* subParams = [self parametersFromIndexOffset:0];
|
||||
IJSVGCommand* command = [self subcommandWithParameters:subParams
|
||||
paramCount:paramCount
|
||||
previousCommand:nil];
|
||||
_subCommands = @[ command ].retain;
|
||||
_subCommands = @[ command ];
|
||||
} else {
|
||||
NSMutableArray<IJSVGCommand*>* subCommandArray = nil;
|
||||
subCommandArray = [[NSMutableArray alloc] initWithCapacity:sets].autorelease;
|
||||
subCommandArray = [[NSMutableArray alloc] initWithCapacity:sets];
|
||||
|
||||
// interate over the sets
|
||||
IJSVGCommand* lastCommand = nil;
|
||||
@@ -239,8 +253,7 @@
|
||||
|
||||
- (void)setSubCommands:(NSArray<IJSVGCommand*>*)subCommands
|
||||
{
|
||||
(void)[_subCommands release], _subCommands = nil;
|
||||
_subCommands = subCommands.retain;
|
||||
_subCommands = subCommands;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
@@ -257,9 +270,9 @@
|
||||
|
||||
IJSVGCommand* lastCommand = nil;
|
||||
NSMutableArray<IJSVGCommand*>* subcommands = nil;
|
||||
subcommands = [[[NSMutableArray alloc] initWithCapacity:self.subCommands.count] autorelease];
|
||||
subcommands = [[NSMutableArray alloc] initWithCapacity:self.subCommands.count];
|
||||
for(IJSVGCommand* subcommand in self.subCommands) {
|
||||
IJSVGCommand* subCopy = [[subcommand copy] autorelease];
|
||||
IJSVGCommand* subCopy = subcommand.copy;
|
||||
subCopy.previousCommand = lastCommand;
|
||||
subCopy.isSubCommand = lastCommand != nil;
|
||||
[subcommands addObject:subCopy];
|
||||
@@ -272,7 +285,7 @@
|
||||
{
|
||||
CGFloat* subParams = 0;
|
||||
NSInteger req = [self.class requiredParameterCount];
|
||||
if (req != 0) {
|
||||
if(req != 0) {
|
||||
subParams = (CGFloat*)malloc(req * sizeof(CGFloat));
|
||||
memcpy(subParams, &self.parameters[index * req], sizeof(CGFloat) * req);
|
||||
}
|
||||
@@ -284,7 +297,7 @@
|
||||
previousCommand:(IJSVGCommand*)aPreviousCommand
|
||||
{
|
||||
// create a subcommand per set
|
||||
IJSVGCommand* c = [[[self.class alloc] init] autorelease];
|
||||
IJSVGCommand* c = [[self.class alloc] init];
|
||||
c.parameterCount = paramCount;
|
||||
c.parameters = subParams;
|
||||
c.type = self.type;
|
||||
@@ -330,9 +343,9 @@
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
NSMutableString* str = [[[NSMutableString alloc] init] autorelease];
|
||||
NSMutableString* str = [[NSMutableString alloc] init];
|
||||
[str appendFormat:@"%c ",_command];
|
||||
NSMutableArray* args = [[[NSMutableArray alloc] initWithCapacity:_parameterCount] autorelease];
|
||||
NSMutableArray* args = [[NSMutableArray alloc] initWithCapacity:_parameterCount];
|
||||
for(int i = 0; i < _parameterCount; i++) {
|
||||
[args addObject:[NSString stringWithFormat:@"%f",_parameters[i]]];
|
||||
}
|
||||
@@ -346,7 +359,7 @@
|
||||
IJSVGCommand* copy = self.copy;
|
||||
[copy convertToUnits:unitType
|
||||
boundingBox:boundingBox];
|
||||
return [copy autorelease];
|
||||
return copy;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommand.h"
|
||||
#import <IJSVG/IJSVGCommand.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGCommandClose : IJSVGCommand
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommandClose.h"
|
||||
#import <IJSVG/IJSVGCommandClose.h>
|
||||
|
||||
@implementation IJSVGCommandClose
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommand.h"
|
||||
#import <IJSVG/IJSVGCommand.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGCommandCurve : IJSVGCommand
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommandCurve.h"
|
||||
#import <IJSVG/IJSVGCommandCurve.h>
|
||||
|
||||
@implementation IJSVGCommandCurve
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
type:(IJSVGCommandType)type
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
if(type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddCurveToPoint(path, NULL, params[0], params[1],
|
||||
params[2], params[3],
|
||||
params[4], params[5]);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommand.h"
|
||||
#import <IJSVG/IJSVGCommand.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGCommandEllipticalArc : IJSVGCommand
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommandEllipticalArc.h"
|
||||
#import "IJSVGUtils.h"
|
||||
#import <IJSVG/IJSVGCommandEllipticalArc.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
|
||||
@implementation IJSVGCommandEllipticalArc
|
||||
|
||||
@@ -49,11 +49,11 @@ static IJSVGPathDataSequence* _sequence;
|
||||
BOOL largeArcFlag = NO;
|
||||
BOOL sweepFlag = NO;
|
||||
|
||||
radii = [currentCommand readPoint];
|
||||
xAxisRotation = [currentCommand readFloat];
|
||||
largeArcFlag = [currentCommand readBOOL];
|
||||
sweepFlag = [currentCommand readBOOL];
|
||||
arcEndPoint = [currentCommand readPoint];
|
||||
radii = currentCommand.readPoint;
|
||||
xAxisRotation = currentCommand.readFloat;
|
||||
largeArcFlag = currentCommand.readBOOL;
|
||||
sweepFlag = currentCommand.readBOOL;
|
||||
arcEndPoint = currentCommand.readPoint;
|
||||
|
||||
CGFloat rx = fabs(radii.x);
|
||||
CGFloat ry = fabs(radii.y);
|
||||
@@ -61,7 +61,7 @@ static IJSVGPathDataSequence* _sequence;
|
||||
xAxisRotation *= M_PI / 180.f;
|
||||
xAxisRotation = fmod(xAxisRotation, 2.f * M_PI);
|
||||
|
||||
if (type == kIJSVGCommandTypeRelative) {
|
||||
if(type == kIJSVGCommandTypeRelative) {
|
||||
arcEndPoint.x += pathCurrentPoint.x;
|
||||
arcEndPoint.y += pathCurrentPoint.y;
|
||||
}
|
||||
@@ -72,7 +72,7 @@ static IJSVGPathDataSequence* _sequence;
|
||||
CGFloat x2 = arcEndPoint.x;
|
||||
CGFloat y2 = arcEndPoint.y;
|
||||
|
||||
if (rx == 0.f || ry == 0.f) {
|
||||
if(rx == 0.f || ry == 0.f) {
|
||||
CGPathAddLineToPoint(path, NULL, x2, y2);
|
||||
return;
|
||||
}
|
||||
@@ -90,7 +90,7 @@ static IJSVGPathDataSequence* _sequence;
|
||||
|
||||
CGFloat delta = xp_2 / rx_2 + yp_2 / ry_2;
|
||||
|
||||
if (delta > 1.f) {
|
||||
if(delta > 1.f) {
|
||||
rx *= sqrt(delta);
|
||||
ry *= sqrt(delta);
|
||||
rx_2 = rx * rx;
|
||||
@@ -120,11 +120,11 @@ static IJSVGPathDataSequence* _sequence;
|
||||
|
||||
CGFloat angleDelta = endAngle - startAngle;;
|
||||
|
||||
if (sweepFlag == YES) {
|
||||
if (angleDelta < 0.f) {
|
||||
if(sweepFlag == YES) {
|
||||
if(angleDelta < 0.f) {
|
||||
angleDelta += 2.f * M_PI;
|
||||
}
|
||||
} else if (angleDelta > 0.f) {
|
||||
} else if(angleDelta > 0.f) {
|
||||
angleDelta = angleDelta - 2.f * M_PI;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommand.h"
|
||||
#import <IJSVG/IJSVGCommand.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGCommandHorizontalLine : IJSVGCommand
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommandHorizontalLine.h"
|
||||
#import <IJSVG/IJSVGCommandHorizontalLine.h>
|
||||
|
||||
@implementation IJSVGCommandHorizontalLine
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
type:(IJSVGCommandType)type
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
if(type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddLineToPoint(path, NULL, params[0], CGPathGetCurrentPoint(path).y);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommand.h"
|
||||
#import <IJSVG/IJSVGCommand.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGCommandLineTo : IJSVGCommand
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommandLineTo.h"
|
||||
#import <IJSVG/IJSVGCommandLineTo.h>
|
||||
|
||||
@implementation IJSVGCommandLineTo
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
type:(IJSVGCommandType)type
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
if(type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddLineToPoint(path, NULL, params[0], params[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommand.h"
|
||||
#import <IJSVG/IJSVGCommand.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGCommandMove : IJSVGCommand
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommandLineTo.h"
|
||||
#import "IJSVGCommandMove.h"
|
||||
#import <IJSVG/IJSVGCommandLineTo.h>
|
||||
#import <IJSVG/IJSVGCommandMove.h>
|
||||
|
||||
@implementation IJSVGCommandMove
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
{
|
||||
// move to's allow more then one move to, but if there are more then one,
|
||||
// we need to run the line to instead...who knew!
|
||||
if (command.class == self.class && currentCommand.isSubCommand == YES) {
|
||||
if(command.class == self.class && currentCommand.isSubCommand == YES) {
|
||||
[IJSVGCommandLineTo runWithParams:params
|
||||
paramCount:count
|
||||
command:currentCommand
|
||||
@@ -40,7 +40,7 @@
|
||||
// relative but there is no previous command which means
|
||||
// there is no current point. Asking for current point on an empty
|
||||
// path will result in an exception being thrown
|
||||
if (type == kIJSVGCommandTypeAbsolute || command == nil) {
|
||||
if(type == kIJSVGCommandTypeAbsolute || command == nil) {
|
||||
CGPathMoveToPoint(path, NULL,
|
||||
params[0], params[1]);
|
||||
return;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommand.h"
|
||||
#import <IJSVG/IJSVGCommand.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGCommandQuadraticCurve : IJSVGCommand
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommandQuadraticCurve.h"
|
||||
#import "IJSVGUtils.h"
|
||||
#import <IJSVG/IJSVGCommandQuadraticCurve.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
|
||||
@implementation IJSVGCommandQuadraticCurve
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
type:(IJSVGCommandType)type
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
if(type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddQuadCurveToPoint(path, NULL, params[0], params[1],
|
||||
params[2], params[3]);
|
||||
return;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommand.h"
|
||||
#import <IJSVG/IJSVGCommand.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGCommandSmoothCurve : IJSVGCommand
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommandCurve.h"
|
||||
#import "IJSVGCommandSmoothCurve.h"
|
||||
#import "IJSVGUtils.h"
|
||||
#import <IJSVG/IJSVGCommandCurve.h>
|
||||
#import <IJSVG/IJSVGCommandSmoothCurve.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
|
||||
@implementation IJSVGCommandSmoothCurve
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
{
|
||||
CGPoint currentPoint = CGPathGetCurrentPoint(path);
|
||||
CGPoint firstControl = CGPointMake(currentPoint.x, currentPoint.y);
|
||||
if (command != nil) {
|
||||
if (command.class == [IJSVGCommandCurve class] || command.class == self.class) {
|
||||
if (command.class == [IJSVGCommandCurve class]) {
|
||||
if (command.type == kIJSVGCommandTypeAbsolute) {
|
||||
if(command != nil) {
|
||||
if(command.class == [IJSVGCommandCurve class] || command.class == self.class) {
|
||||
if(command.class == [IJSVGCommandCurve class]) {
|
||||
if(command.type == kIJSVGCommandTypeAbsolute) {
|
||||
firstControl = CGPointMake(-1 * command.parameters[2] + 2 * currentPoint.x,
|
||||
-1 * command.parameters[3] + 2 * currentPoint.y);
|
||||
} else {
|
||||
@@ -39,7 +39,7 @@
|
||||
-1 * (command.parameters[3] + oldPoint.y) + 2 * currentPoint.y);
|
||||
}
|
||||
} else {
|
||||
if (command.type == kIJSVGCommandTypeAbsolute) {
|
||||
if(command.type == kIJSVGCommandTypeAbsolute) {
|
||||
firstControl = CGPointMake(-1 * command.parameters[0] + 2 * currentPoint.x,
|
||||
-1 * command.parameters[1] + 2 * currentPoint.y);
|
||||
} else {
|
||||
@@ -51,7 +51,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
if(type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddCurveToPoint(path, NULL, firstControl.x, firstControl.y,
|
||||
params[0], params[1], params[2], params[3]);
|
||||
return;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommand.h"
|
||||
#import <IJSVG/IJSVGCommand.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGCommandSmoothQuadraticCurve : IJSVGCommand
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommandQuadraticCurve.h"
|
||||
#import "IJSVGCommandSmoothQuadraticCurve.h"
|
||||
#import "IJSVGUtils.h"
|
||||
#import <IJSVG/IJSVGCommandQuadraticCurve.h>
|
||||
#import <IJSVG/IJSVGCommandSmoothQuadraticCurve.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
|
||||
@implementation IJSVGCommandSmoothQuadraticCurve
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
CGPoint lastControlPoint = IJSVGPathGetLastQuadraticCommandPoint(path);
|
||||
CGPoint currentPoint = CGPathGetCurrentPoint(path);
|
||||
CGPoint commandPoint = CGPointMake(currentPoint.x, currentPoint.y);
|
||||
if (command != nil) {
|
||||
if (command.class == IJSVGCommandQuadraticCurve.class) {
|
||||
if(command != nil) {
|
||||
if(command.class == IJSVGCommandQuadraticCurve.class) {
|
||||
// quadratic curve
|
||||
if (command.type == kIJSVGCommandTypeAbsolute) {
|
||||
if(command.type == kIJSVGCommandTypeAbsolute) {
|
||||
commandPoint = NSMakePoint(-1 * command.parameters[0] + 2 * currentPoint.x,
|
||||
-1 * command.parameters[1] + 2 * currentPoint.y);
|
||||
} else {
|
||||
@@ -39,14 +39,14 @@
|
||||
commandPoint = CGPointMake(-1 * (command.parameters[0] + oldPoint.x) + 2 * (currentPoint.x),
|
||||
-1 * (command.parameters[1] + oldPoint.y) + 2 * currentPoint.y);
|
||||
}
|
||||
} else if (command.class == self.class) {
|
||||
} else if(command.class == self.class) {
|
||||
// smooth quadratic curve
|
||||
commandPoint = CGPointMake(-1 * (lastControlPoint.x) + 2 * (currentPoint.x),
|
||||
-1 * (lastControlPoint.y) + 2 * currentPoint.y);
|
||||
}
|
||||
}
|
||||
// path.lastControlPoint = commandPoint;
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
if(type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddQuadCurveToPoint(path, NULL, commandPoint.x, commandPoint.y,
|
||||
params[0], params[1]);
|
||||
return;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommand.h"
|
||||
#import <IJSVG/IJSVGCommand.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGCommandVerticalLine : IJSVGCommand
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGCommandVerticalLine.h"
|
||||
#import <IJSVG/IJSVGCommandVerticalLine.h>
|
||||
|
||||
@implementation IJSVGCommandVerticalLine
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
type:(IJSVGCommandType)type
|
||||
path:(CGMutablePathRef)path
|
||||
{
|
||||
if (type == kIJSVGCommandTypeAbsolute) {
|
||||
if(type == kIJSVGCommandTypeAbsolute) {
|
||||
CGPathAddLineToPoint(path, NULL, CGPathGetCurrentPoint(path).x, params[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGColorList.h>
|
||||
#import <IJSVG/IJSVGTraitedColorStorage.h>
|
||||
#import <IJSVG/IJSVGRootNode.h>
|
||||
#import <IJSVG/IJSVGExporter.h>
|
||||
#import <IJSVG/IJSVGGradientLayer.h>
|
||||
@@ -16,42 +16,20 @@
|
||||
#import <IJSVG/IJSVGLayerTree.h>
|
||||
#import <IJSVG/IJSVGParser.h>
|
||||
#import <IJSVG/IJSVGRendering.h>
|
||||
#import <IJSVG/IJSVGRenderingStyle.h>
|
||||
#import <IJSVG/IJSVGStyle.h>
|
||||
#import <IJSVG/IJSVGTransaction.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class IJSVG;
|
||||
|
||||
typedef NS_OPTIONS(NSInteger, IJSVGMatchPropertiesMask) {
|
||||
IJSVGMatchPropertyNone = 0,
|
||||
IJSVGMatchPropertyContainsMaskedElement = 1 << 0,
|
||||
IJSVGMatchPropertyContainsStrokedElement = 1 << 1
|
||||
};
|
||||
|
||||
@protocol IJSVGDelegate <NSObject, IJSVGParserDelegate>
|
||||
|
||||
@optional
|
||||
- (void)svg:(IJSVG*)svg
|
||||
foundSubSVG:(IJSVG*)subSVG
|
||||
withSVGString:(NSString*)subSVGString;
|
||||
|
||||
@end
|
||||
|
||||
@interface IJSVG : NSObject <NSPasteboardWriting, IJSVGParserDelegate> {
|
||||
@interface IJSVG : NSObject <NSPasteboardWriting> {
|
||||
|
||||
@private
|
||||
IJSVGRootNode* _rootNode;
|
||||
CGFloat _scale;
|
||||
CGFloat _clipScale;
|
||||
id<IJSVGDelegate> _delegate;
|
||||
IJSVGLayerTree* _layerTree;
|
||||
CGRect _viewBox;
|
||||
CGFloat _backingScale;
|
||||
NSMutableDictionary* _replacementColors;
|
||||
|
||||
struct {
|
||||
unsigned int shouldHandleSubSVG : 1;
|
||||
} _respondsTo;
|
||||
IJSVGUnitSize* _intrinsicSize;
|
||||
}
|
||||
|
||||
// set this to be called when the layer is about to draw, it will call this
|
||||
@@ -63,37 +41,60 @@ withSVGString:(NSString*)subSVGString;
|
||||
// global overwriting rules for when rendering an SVG, this will overide any
|
||||
// fillColor, strokeColor, pattern and gradient fill
|
||||
@property (nonatomic, assign) IJSVGRenderQuality renderQuality;
|
||||
@property (nonatomic, assign) BOOL clipToViewport;
|
||||
@property (nonatomic, retain) IJSVGRenderingStyle* renderingStyle;
|
||||
@property (nonatomic, readonly) IJSVGUnitSize * intrinsicSize;
|
||||
@property (nonatomic, strong) IJSVGStyle* style;
|
||||
|
||||
@property (nonatomic, copy) NSString* title;
|
||||
@property (nonatomic, copy) NSString* desc;
|
||||
@property (nonatomic, retain) IJSVGLayerTree* layerTree;
|
||||
@property (nonatomic, retain) IJSVGRootLayer* rootLayer;
|
||||
@property (nonatomic, strong) IJSVGLayerTree* layerTree;
|
||||
@property (nonatomic, strong) IJSVGRootLayer* rootLayer;
|
||||
@property (nonatomic, assign) BOOL ignoreIntrinsicSize;
|
||||
|
||||
@property (nonatomic, readonly) IJSVGTraitedColorStorage* colors;
|
||||
|
||||
// The size of the SVG either computed by its intrinsicSize of its viewBox
|
||||
// If the size if % values, it will use the defaultSize
|
||||
@property (nonatomic, readonly) CGSize size;
|
||||
|
||||
// Will return true if the intrinsic size is a % value
|
||||
@property (nonatomic, readonly) BOOL hasDynamicSize;
|
||||
|
||||
// This is used when the intrinsic size is a % value, e.g. 100% x 100%
|
||||
@property (nonatomic, assign) CGSize defaultSize;
|
||||
|
||||
// bitmask of which dimentions were implicitly set on the SVG
|
||||
@property (nonatomic, readonly) IJSVGIntrinsicDimensions intrinsicDimensions;
|
||||
|
||||
- (void)prepForDrawingInView:(NSView*)view;
|
||||
- (BOOL)isFont;
|
||||
- (IJSVGGroup*)rootNode;
|
||||
- (NSRect)viewBox;
|
||||
- (NSArray<IJSVGPath*>*)glyphs;
|
||||
- (IJSVGRootNode*)rootNode;
|
||||
- (CGRect)viewBox;
|
||||
- (CGSize)sizeWithDefaultSize:(CGSize)size;
|
||||
- (CGSize)sizeByMaintainingAspectRatioWithSize:(CGSize)aSize;
|
||||
- (NSString*)identifier;
|
||||
- (NSArray<IJSVG*>*)subSVGs:(BOOL)recursive;
|
||||
- (NSSet<IJSVG*>*)directDescendSVGs;
|
||||
- (IJSVGExporter*)exporterWithSize:(CGSize)size
|
||||
options:(IJSVGExporterOptions)options
|
||||
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions;
|
||||
- (NSString*)SVGStringWithSize:(CGSize)size
|
||||
options:(IJSVGExporterOptions)options;
|
||||
- (NSString*)SVGStringWithSize:(CGSize)size
|
||||
options:(IJSVGExporterOptions)options
|
||||
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions;
|
||||
- (NSString*)SVGStringWithOptions:(IJSVGExporterOptions)options;
|
||||
- (NSString*)SVGStringWithOptions:(IJSVGExporterOptions)options
|
||||
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions;
|
||||
|
||||
+ (id)svgNamed:(NSString*)string;
|
||||
+ (id)svgNamed:(NSString*)string
|
||||
delegate:(id<IJSVGDelegate>)delegate;
|
||||
+ (id)SVGNamed:(NSString*)string;
|
||||
|
||||
+ (IJSVG*)SVGFromCGPathRef:(CGPathRef)path;
|
||||
+ (IJSVG*)SVGFromCGPathRef:(CGPathRef)path
|
||||
flipped:(BOOL)flipped;
|
||||
|
||||
|
||||
- (id)initWithImage:(NSImage*)image;
|
||||
- (id)initWithRootNode:(IJSVGRootNode*)rootNode;
|
||||
|
||||
- (id)initWithSVGLayer:(IJSVGGroupLayer*)group
|
||||
viewBox:(NSRect)viewBox;
|
||||
|
||||
- (id)initWithSVGString:(NSString*)string
|
||||
error:(NSError**)error
|
||||
delegate:(id<IJSVGDelegate>)delegate;
|
||||
viewBox:(CGRect)viewBox;
|
||||
|
||||
- (id)initWithSVGString:(NSString*)string;
|
||||
- (id)initWithSVGString:(NSString*)string
|
||||
@@ -106,19 +107,9 @@ withSVGString:(NSString*)subSVGString;
|
||||
- (id)initWithFile:(NSString*)file;
|
||||
- (id)initWithFile:(NSString*)file
|
||||
error:(NSError**)error;
|
||||
- (id)initWithFile:(NSString*)file
|
||||
delegate:(id<IJSVGDelegate>)delegate;
|
||||
- (id)initWithFile:(NSString*)file
|
||||
error:(NSError**)error
|
||||
delegate:(id<IJSVGDelegate>)delegate;
|
||||
- (id)initWithFilePathURL:(NSURL*)aURL;
|
||||
- (id)initWithFilePathURL:(NSURL*)aURL
|
||||
error:(NSError**)error;
|
||||
- (id)initWithFilePathURL:(NSURL*)aURL
|
||||
delegate:(id<IJSVGDelegate>)delegate;
|
||||
- (id)initWithFilePathURL:(NSURL*)aURL
|
||||
error:(NSError**)error
|
||||
delegate:(id<IJSVGDelegate>)delegate;
|
||||
|
||||
- (id)initWithDataAssetNamed:(NSDataAssetName)name
|
||||
error:(NSError**)error;
|
||||
@@ -126,45 +117,44 @@ withSVGString:(NSString*)subSVGString;
|
||||
bundle:(NSBundle*)bundle
|
||||
error:(NSError**)error;
|
||||
|
||||
- (NSImage*)imageWithSize:(NSSize)aSize;
|
||||
- (NSImage*)imageWithSize:(NSSize)aSize
|
||||
- (NSImage*)imageWithSize:(CGSize)aSize;
|
||||
- (NSImage*)imageWithSize:(CGSize)aSize
|
||||
error:(NSError**)error;
|
||||
- (NSImage*)imageWithSize:(NSSize)aSize
|
||||
- (NSImage*)imageWithSize:(CGSize)aSize
|
||||
flipped:(BOOL)flipped;
|
||||
- (NSImage*)imageWithSize:(NSSize)aSize
|
||||
- (NSImage*)imageWithSize:(CGSize)aSize
|
||||
flipped:(BOOL)flipped
|
||||
error:(NSError**)error;
|
||||
- (NSImage*)imageByMaintainingAspectRatioWithSize:(NSSize)aSize
|
||||
- (NSImage*)imageByMaintainingAspectRatioWithSize:(CGSize)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
|
||||
size:(NSSize)aSize
|
||||
- (BOOL)drawAtPoint:(CGPoint)point
|
||||
size:(CGSize)size;
|
||||
- (BOOL)drawAtPoint:(CGPoint)point
|
||||
size:(CGSize)aSize
|
||||
error:(NSError**)error;
|
||||
- (BOOL)drawInRect:(NSRect)rect;
|
||||
- (BOOL)drawInRect:(NSRect)rect
|
||||
- (BOOL)drawInRect:(CGRect)rect;
|
||||
- (BOOL)drawInRect:(CGRect)rect
|
||||
error:(NSError**)error;
|
||||
- (void)drawInRect:(NSRect)rect
|
||||
- (void)drawInRect:(CGRect)rect
|
||||
context:(CGContextRef)context;
|
||||
|
||||
- (NSData*)PDFData;
|
||||
- (NSData*)PDFData:(NSError**)error;
|
||||
- (NSData*)PDFDataWithRect:(NSRect)rect;
|
||||
- (NSData*)PDFDataWithRect:(NSRect)rect
|
||||
- (NSData*)PDFDataWithRect:(CGRect)rect;
|
||||
- (NSData*)PDFDataWithRect:(CGRect)rect
|
||||
error:(NSError**)error;
|
||||
|
||||
- (NSRect)computeOriginalDrawingFrameWithSize:(NSSize)aSize;
|
||||
// call this to invalidate the render tree when you change the style
|
||||
- (void)setNeedsDisplay;
|
||||
|
||||
// colors
|
||||
- (IJSVGColorList*)colorList;
|
||||
- (void)performBlock:(dispatch_block_t)block;
|
||||
|
||||
// matching
|
||||
- (BOOL)matchesPropertiesWithMask:(IJSVGMatchPropertiesMask)mask;
|
||||
- (BOOL)containsNodesMatchingTraits:(IJSVGNodeTraits)mask;
|
||||
@end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +0,0 @@
|
||||
//
|
||||
// IJSVGFontConverter.h
|
||||
// IJSVGExample
|
||||
//
|
||||
// Created by Curtis Hard on 21/05/2015.
|
||||
// Copyright (c) 2015 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVG.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef void (^IJSVGFontConverterEnumerateBlock)(NSString* unicode, IJSVG* svg);
|
||||
|
||||
@interface IJSVGFontConverter : NSObject {
|
||||
|
||||
@private
|
||||
NSURL* _url;
|
||||
NSFont* _font;
|
||||
NSMutableDictionary<NSString*, id>* _transformedPaths;
|
||||
}
|
||||
|
||||
- (id)initWithFontAtFileURL:(NSURL*)url;
|
||||
- (NSFont*)font;
|
||||
- (void)enumerateUsingBlock:(IJSVGFontConverterEnumerateBlock)block;
|
||||
|
||||
+ (IJSVG*)convertIJSVGPathToSVG:(IJSVGPath*)path;
|
||||
+ (IJSVG*)convertPathToSVG:(CGPathRef)path;
|
||||
|
||||
@end
|
||||
@@ -1,127 +0,0 @@
|
||||
//
|
||||
// IJSVGFontConverter.m
|
||||
// IJSVGExample
|
||||
//
|
||||
// Created by Curtis Hard on 21/05/2015.
|
||||
// Copyright (c) 2015 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGFontConverter.h"
|
||||
#import "IJSVGShapeLayer.h"
|
||||
|
||||
@implementation IJSVGFontConverter
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_transformedPaths release]), _transformedPaths = nil;
|
||||
(void)([_url release]), _url = nil;
|
||||
(void)([_font release]), _font = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)initWithFontAtFileURL:(NSURL*)url
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
_url = [url copy];
|
||||
|
||||
// load the font
|
||||
CGDataProviderRef dataProvider = CGDataProviderCreateWithURL((CFURLRef)_url);
|
||||
CGFontRef fontRef = CGFontCreateWithDataProvider(dataProvider);
|
||||
CTFontRef font = CTFontCreateWithGraphicsFont(fontRef, 30.f, NULL, NULL);
|
||||
|
||||
// toll free bridge between NSFont at CTFont :)
|
||||
_font = [(NSFont*)font copy];
|
||||
CGFontRelease(fontRef);
|
||||
CGDataProviderRelease(dataProvider);
|
||||
CFRelease(font);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSFont*)font
|
||||
{
|
||||
return _font;
|
||||
}
|
||||
|
||||
- (NSArray*)allCharacters
|
||||
{
|
||||
NSCharacterSet* charSet = _font.coveredCharacterSet;
|
||||
NSMutableArray* array = [[[NSMutableArray alloc] init] autorelease];
|
||||
NSStringEncoding encoding = NSUTF32LittleEndianStringEncoding;
|
||||
for (int plane = 0; plane <= 16; plane++) {
|
||||
if ([charSet hasMemberInPlane:plane]) {
|
||||
UTF32Char c;
|
||||
for (c = plane << 16; c < (plane + 1) << 16; c++) {
|
||||
if ([charSet longCharacterIsMember:c]) {
|
||||
UTF32Char c1 = NSSwapHostIntToLittle(c);
|
||||
[array addObject:[[[NSString alloc] initWithBytes:&c1
|
||||
length:4
|
||||
encoding:encoding] autorelease]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
- (void)generateMap
|
||||
{
|
||||
CTFontRef font = (CTFontRef)_font;
|
||||
for (NSString* charString in [self allCharacters]) {
|
||||
// get the characters in each char
|
||||
NSUInteger count = charString.length;
|
||||
unichar characters[count];
|
||||
[charString getCharacters:characters
|
||||
range:NSMakeRange(0, count)];
|
||||
|
||||
// get the glyphs
|
||||
CGGlyph glyphs[count];
|
||||
CTFontGetGlyphsForCharacters(font, characters, glyphs, count);
|
||||
CGPathRef path = CTFontCreatePathForGlyph(font, glyphs[0], NULL);
|
||||
if (path != NULL) {
|
||||
// add SVG to the dictionary
|
||||
NSString* key = [NSString stringWithFormat:@"%04x", [charString characterAtIndex:0]];
|
||||
CGPathRef flippedPath = [IJSVGUtils newFlippedCGPath:path];
|
||||
_transformedPaths[key] = (id)flippedPath;
|
||||
CGPathRelease(flippedPath);
|
||||
}
|
||||
CGPathRelease(path);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)enumerateUsingBlock:(IJSVGFontConverterEnumerateBlock)block
|
||||
{
|
||||
if (_transformedPaths == nil) {
|
||||
_transformedPaths = [[NSMutableDictionary alloc] init];
|
||||
[self generateMap];
|
||||
}
|
||||
|
||||
for (NSString* key in _transformedPaths.allKeys) {
|
||||
block(key, [self.class convertPathToSVG:(CGPathRef)_transformedPaths[key]]);
|
||||
}
|
||||
}
|
||||
|
||||
+ (IJSVG*)convertIJSVGPathToSVG:(IJSVGPath*)path
|
||||
{
|
||||
CGPathRef flippedPath = [IJSVGUtils newFlippedCGPath:path.path];
|
||||
IJSVG* svg = [self convertPathToSVG:flippedPath];
|
||||
CGPathRelease(flippedPath);
|
||||
return svg;
|
||||
}
|
||||
|
||||
+ (IJSVG*)convertPathToSVG:(CGPathRef)path
|
||||
{
|
||||
IJSVGBeginTransaction();
|
||||
__block IJSVG* svg = nil;
|
||||
IJSVGGroupLayer* layer = [[[IJSVGGroupLayer alloc] init] autorelease];
|
||||
IJSVGShapeLayer* shape = [[[IJSVGShapeLayer alloc] init] autorelease];
|
||||
[layer addSublayer:shape];
|
||||
shape.path = path;
|
||||
CGRect box = CGPathGetPathBoundingBox(path);
|
||||
svg = [[IJSVG alloc] initWithSVGLayer:layer
|
||||
viewBox:box];
|
||||
IJSVGEndTransaction();
|
||||
return [svg autorelease];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGParser.h"
|
||||
#import <IJSVG/IJSVGParser.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class IJSVG;
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVG.h"
|
||||
#import "IJSVGImageRep.h"
|
||||
#import <IJSVG/IJSVG.h>
|
||||
#import <IJSVG/IJSVGImageRep.h>
|
||||
|
||||
@implementation IJSVGImageRep
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
+ (NSArray<NSString*>*)imageTypes
|
||||
{
|
||||
if (@available(macOS 10.10, *)) {
|
||||
if(@available(macOS 10.10, *)) {
|
||||
return @[ (NSString*)kUTTypeScalableVectorGraphics, @"svg" ];
|
||||
} else {
|
||||
return @[ @"public.svg-image", @"svg" ];
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
+ (NSArray<NSString*>*)imageUnfilteredTypes
|
||||
{
|
||||
if (@available(macOS 10.10, *)) {
|
||||
if(@available(macOS 10.10, *)) {
|
||||
return @[ (NSString*)kUTTypeScalableVectorGraphics, @"svg" ];
|
||||
} else {
|
||||
return @[ @"public.svg-image", @"svg" ];
|
||||
@@ -42,7 +42,7 @@
|
||||
+ (NSArray<NSImageRep*>*)imageRepsWithData:(NSData*)data
|
||||
{
|
||||
IJSVGImageRep* instance = [self imageRepWithData:data];
|
||||
if (instance == nil) {
|
||||
if(instance == nil) {
|
||||
return @[];
|
||||
}
|
||||
return @[ instance ];
|
||||
@@ -50,28 +50,21 @@
|
||||
|
||||
+ (instancetype)imageRepWithData:(NSData*)data
|
||||
{
|
||||
return [[[self alloc] initWithData:data] autorelease];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_svg release]), _svg = nil;
|
||||
[super dealloc];
|
||||
return [[self alloc] initWithData:data];
|
||||
}
|
||||
|
||||
- (instancetype)initWithData:(NSData*)data
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
if((self = [super init]) != nil) {
|
||||
// grab the string from the data
|
||||
// its more then likely UTF-8...
|
||||
NSString* string = [[[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding] autorelease];
|
||||
NSString* string = [[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding];
|
||||
|
||||
_svg = [[IJSVG alloc] initWithSVGString:string];
|
||||
|
||||
// no valid SVG, just return nil;
|
||||
if (_svg == nil) {
|
||||
[self release];
|
||||
if(_svg == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// IJSVGUmbrella.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 16/04/2023.
|
||||
// Copyright © 2023 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef IJSVGUmbrella_h
|
||||
#define IJSVGUmbrella_h
|
||||
|
||||
#import <IJSVG/IJSVG.h>
|
||||
#import <IJSVG/IJSVGCommandClose.h>
|
||||
#import <IJSVG/IJSVGCommandCurve.h>
|
||||
#import <IJSVG/IJSVGCommandEllipticalArc.h>
|
||||
#import <IJSVG/IJSVGCommandHorizontalLine.h>
|
||||
#import <IJSVG/IJSVGCommandLineTo.h>
|
||||
#import <IJSVG/IJSVGCommandMove.h>
|
||||
#import <IJSVG/IJSVGCommandQuadraticCurve.h>
|
||||
#import <IJSVG/IJSVGCommandSmoothQuadraticCurve.h>
|
||||
#import <IJSVG/IJSVGCommandSmoothCurve.h>
|
||||
#import <IJSVG/IJSVGCommandVerticalLine.h>
|
||||
#import <IJSVG/IJSVGExporterPathInstruction.h>
|
||||
#import <IJSVG/IJSVGFeatureFlag.h>
|
||||
#import <IJSVG/IJSVGFeatureFlags.h>
|
||||
#import <IJSVG/IJSVGFilterEffectGaussianBlur.h>
|
||||
#import <IJSVG/IJSVGFilterLayer.h>
|
||||
#import <IJSVG/IJSVGImageRep.h>
|
||||
#import <IJSVG/IJSVGMath.h>
|
||||
#import <IJSVG/IJSVGParsing.h>
|
||||
#import <IJSVG/IJSVGPatternLayer.h>
|
||||
#import <IJSVG/IJSVGStrokeLayer.h>
|
||||
#import <IJSVG/IJSVGThreadManager.h>
|
||||
#import <IJSVG/IJSVGView.h>
|
||||
#import <IJSVG/NSImage+IJSVGAdditions.h>
|
||||
|
||||
#endif /* IJSVGUmbrella_h */
|
||||
@@ -17,7 +17,7 @@ IB_DESIGNABLE
|
||||
IJSVG* SVG;
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) IJSVG* SVG;
|
||||
@property (nonatomic, strong) IJSVG* SVG;
|
||||
|
||||
+ (IJSVGView*)viewWithSVGNamed:(NSString*)name;
|
||||
- (id)initWithSVG:(IJSVG*)anSvg;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2017 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGView.h"
|
||||
#import <IJSVG/IJSVGView.h>
|
||||
|
||||
@implementation IJSVGView
|
||||
|
||||
@@ -17,20 +17,17 @@
|
||||
// make sure we call this, or block may get called for a view
|
||||
// that doesnt exist
|
||||
[SVG prepForDrawingInView:nil];
|
||||
(void)([imageName release]), imageName = nil;
|
||||
(void)([SVG release]), SVG = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
+ (IJSVGView*)viewWithSVGNamed:(NSString*)name
|
||||
{
|
||||
IJSVG* anSVG = [IJSVG svgNamed:name];
|
||||
return [[[self alloc] initWithSVG:anSVG] autorelease];
|
||||
IJSVG* anSVG = [IJSVG SVGNamed:name];
|
||||
return [[self alloc] initWithSVG:anSVG];
|
||||
}
|
||||
|
||||
- (id)initWithSVG:(IJSVG*)anSvg
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
if((self = [super init]) != nil) {
|
||||
self.SVG = anSvg;
|
||||
}
|
||||
return self;
|
||||
@@ -39,10 +36,10 @@
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
// image was set via IB
|
||||
if (imageName != nil) {
|
||||
IJSVG* anSVG = [IJSVG svgNamed:imageName];
|
||||
if (tintColor != nil) {
|
||||
anSVG.renderingStyle.fillColor = tintColor;
|
||||
if(imageName != nil) {
|
||||
IJSVG* anSVG = [IJSVG SVGNamed:imageName];
|
||||
if(tintColor != nil) {
|
||||
anSVG.style.fillColor = tintColor;
|
||||
}
|
||||
self.SVG = anSVG;
|
||||
}
|
||||
@@ -51,10 +48,7 @@
|
||||
- (void)setSVG:(IJSVG*)anSVG
|
||||
{
|
||||
// memory clean
|
||||
if (SVG != nil) {
|
||||
(void)([SVG release]), SVG = nil;
|
||||
}
|
||||
SVG = [anSVG retain];
|
||||
SVG = anSVG;
|
||||
|
||||
// redisplay ourself!
|
||||
[SVG prepForDrawingInView:self];
|
||||
@@ -69,7 +63,7 @@
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
{
|
||||
// only draw if there is actually an SVG
|
||||
if (self.SVG == nil) {
|
||||
if(self.SVG == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
#import <IJSVG/IJSVGColorType.h>
|
||||
#import <IJSVG/IJSVGTraitedColor.h>
|
||||
|
||||
@class IJSVG;
|
||||
@class IJSVGExporter;
|
||||
@@ -32,10 +32,10 @@ typedef NS_OPTIONS(NSInteger, IJSVGExporterOptions) {
|
||||
IJSVGExporterOptionCollapseGroups = 1 << 6,
|
||||
IJSVGExporterOptionCleanupPaths = 1 << 7,
|
||||
IJSVGExporterOptionRemoveHiddenElements = 1 << 8,
|
||||
IJSVGExporterOptionScaleToSizeIfNecessary = 1 << 9,
|
||||
IJSVGExporterOptionScaleToSizeIfNecessary DEPRECATED_ATTRIBUTE = 1 << 9,
|
||||
IJSVGExporterOptionCompressOutput = 1 << 10,
|
||||
IJSVGExporterOptionCollapseGradients = 1 << 11,
|
||||
IJSVGExporterOptionCreateClasses = 1 << 12,
|
||||
IJSVGExporterOptionCreateClasses DEPRECATED_ATTRIBUTE = 1 << 12,
|
||||
IJSVGExporterOptionRemoveWidthHeightAttributes = 1 << 13,
|
||||
IJSVGExporterOptionColorAllowRRGGBBAA = 1 << 14,
|
||||
IJSVGExporterOptionRemoveComments = 1 << 15,
|
||||
@@ -45,16 +45,17 @@ typedef NS_OPTIONS(NSInteger, IJSVGExporterOptions) {
|
||||
IJSVGExporterOptionConvertShapesToPaths = 1 << 19,
|
||||
IJSVGExporterOptionRoundTransforms = 1 << 20,
|
||||
IJSVGExporterOptionRemoveDefaultValues = 1 << 21,
|
||||
IJSVGExporterOptionConvertStrokesToPaths = 1 << 22,
|
||||
IJSVGExporterOptionAll = IJSVGExporterOptionRemoveUselessDef | IJSVGExporterOptionRemoveUselessGroups |
|
||||
IJSVGExporterOptionCreateUseForPaths | IJSVGExporterOptionMoveAttributesToGroup |
|
||||
IJSVGExporterOptionSortAttributes | IJSVGExporterOptionCollapseGroups |
|
||||
IJSVGExporterOptionCleanupPaths | IJSVGExporterOptionRemoveHiddenElements |
|
||||
IJSVGExporterOptionScaleToSizeIfNecessary | IJSVGExporterOptionCompressOutput |
|
||||
IJSVGExporterOptionCleanupPaths | IJSVGExporterOptionRemoveHiddenElements | IJSVGExporterOptionCompressOutput |
|
||||
IJSVGExporterOptionCollapseGradients | IJSVGExporterOptionRemoveWidthHeightAttributes |
|
||||
IJSVGExporterOptionColorAllowRRGGBBAA | IJSVGExporterOptionRemoveComments |
|
||||
IJSVGExporterOptionCenterWithinViewBox | IJSVGExporterOptionRemoveXMLDeclaration |
|
||||
IJSVGExporterOptionConvertArcs | IJSVGExporterOptionConvertShapesToPaths |
|
||||
IJSVGExporterOptionRoundTransforms | IJSVGExporterOptionRemoveDefaultValues
|
||||
IJSVGExporterOptionRoundTransforms | IJSVGExporterOptionRemoveDefaultValues |
|
||||
IJSVGExporterOptionConvertStrokesToPaths
|
||||
};
|
||||
|
||||
BOOL IJSVGExporterHasOption(IJSVGExporterOptions options, NSInteger option);
|
||||
@@ -72,7 +73,7 @@ const NSDictionary<NSString*, NSString*>* IJSVGDefaultAttributes(void);
|
||||
defaultID:(NSString* (^)(void))defaultID;
|
||||
- (NSString* _Nullable)svgExporter:(IJSVGExporter*)exporter
|
||||
stringForColor:(NSColor*)color
|
||||
flags:(IJSVGColorTypeFlags)flag
|
||||
flags:(IJSVGColorUsageTraits)flag
|
||||
options:(IJSVGColorStringOptions)options;
|
||||
|
||||
|
||||
@@ -89,6 +90,7 @@ const NSDictionary<NSString*, NSString*>* IJSVGDefaultAttributes(void);
|
||||
NSInteger _idCount;
|
||||
NSInteger _shortIdCount;
|
||||
BOOL _appliedXLink;
|
||||
IJSVGThreadManager* _threadManager;
|
||||
|
||||
struct {
|
||||
unsigned int identifierForElement: 1;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,15 +10,13 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef struct {
|
||||
char instruction;
|
||||
NSArray<NSString*>* params;
|
||||
} IJSVGExporterPathInstructionCommand;
|
||||
@interface IJSVGExporterPathInstructionCommand : NSObject {
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
CGPoint center;
|
||||
CGFloat radius;
|
||||
} IJSVGExporterPathInstructionCircle;
|
||||
@property (nonatomic, assign) char instruction;
|
||||
@property (nonatomic, strong) NSArray<NSString*>* params;
|
||||
|
||||
@end
|
||||
|
||||
@interface IJSVGExporterPathInstruction : NSObject {
|
||||
|
||||
@@ -33,8 +31,6 @@ typedef struct {
|
||||
|
||||
void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length, IJSVGFloatingPointOptions options);
|
||||
CGFloat IJSVGExporterPathFloatToFixed(CGFloat number, int precision);
|
||||
IJSVGExporterPathInstructionCommand* IJSVGExporterPathInstructionCommandCopy(IJSVGExporterPathInstructionCommand command);
|
||||
void IJSVGExporterPathInstructionCommandFree(IJSVGExporterPathInstructionCommand* _Nullable command);
|
||||
|
||||
+ (NSArray<IJSVGExporterPathInstruction*>*)instructionsFromPath:(CGPathRef)path
|
||||
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions;
|
||||
|
||||
@@ -6,37 +6,39 @@
|
||||
// Copyright © 2017 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGExporter.h"
|
||||
#import "IJSVGExporterPathInstruction.h"
|
||||
#import "IJSVGUtils.h"
|
||||
#import <IJSVG/IJSVGExporter.h>
|
||||
#import <IJSVG/IJSVGExporterPathInstruction.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
#import <math.h>
|
||||
|
||||
@implementation IJSVGExporterPathInstructionCommand
|
||||
@end
|
||||
|
||||
@implementation IJSVGExporterPathInstruction
|
||||
|
||||
@synthesize instruction = _instruction;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (_data != NULL) {
|
||||
if(_data != NULL) {
|
||||
(void)free(_data), _data = NULL;
|
||||
}
|
||||
if (_base != NULL) {
|
||||
if(_base != NULL) {
|
||||
(void)free(_base), _base = NULL;
|
||||
}
|
||||
if (_coords != NULL) {
|
||||
if(_coords != NULL) {
|
||||
(void)free(_coords), _coords = NULL;
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)initWithInstruction:(char)instruction
|
||||
dataCount:(NSInteger)floatCount
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
if((self = [super init]) != nil) {
|
||||
_instruction = instruction;
|
||||
|
||||
// only allocate if not zero
|
||||
if (floatCount != 0) {
|
||||
if(floatCount != 0) {
|
||||
_dataCount = floatCount;
|
||||
_data = (CGFloat*)calloc(sizeof(CGFloat), floatCount);
|
||||
}
|
||||
@@ -68,36 +70,18 @@
|
||||
return _coords;
|
||||
}
|
||||
|
||||
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
|
||||
+ (NSString*)pathStringWithInstructionSet:(NSArray<IJSVGExporterPathInstructionCommand*>*)instructionSets
|
||||
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions
|
||||
{
|
||||
IJSVGExporterPathInstructionCommand* lastCommand = NULL;
|
||||
NSMutableString* string = [[[NSMutableString alloc] init] autorelease];
|
||||
for (NSValue* value in instructionSets) {
|
||||
NSMutableString* string = [[NSMutableString alloc] init];
|
||||
for (IJSVGExporterPathInstructionCommand* command 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)) {
|
||||
if(lastCommand == nil || (lastCommand != nil && lastCommand.instruction != command.instruction)) {
|
||||
[string appendFormat:@"%c", command.instruction];
|
||||
} else {
|
||||
[string appendString:@" "];
|
||||
@@ -108,18 +92,15 @@ void IJSVGExporterPathInstructionCommandFree(IJSVGExporterPathInstructionCommand
|
||||
[string appendString:compressedFloats];
|
||||
|
||||
// store last command
|
||||
IJSVGExporterPathInstructionCommandFree(lastCommand);
|
||||
lastCommand = IJSVGExporterPathInstructionCommandCopy(command);
|
||||
lastCommand = command;
|
||||
}
|
||||
|
||||
IJSVGExporterPathInstructionCommandFree(lastCommand);
|
||||
return string;
|
||||
}
|
||||
|
||||
+ (NSString*)pathStringFromInstructions:(NSArray<IJSVGExporterPathInstruction*>*)instructions
|
||||
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions
|
||||
{
|
||||
NSMutableArray* pathInstructions = [[[NSMutableArray alloc] init] autorelease];
|
||||
NSMutableArray* pathInstructions = [[NSMutableArray alloc] init];
|
||||
for (IJSVGExporterPathInstruction* instruction in instructions) {
|
||||
CGFloat* data = instruction.data;
|
||||
const char lowerInstruction = tolower(instruction.instruction);
|
||||
@@ -186,14 +167,11 @@ void IJSVGExporterPathInstructionCommandFree(IJSVGExporterPathInstructionCommand
|
||||
}
|
||||
|
||||
// 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];
|
||||
IJSVGExporterPathInstructionCommand* wrapperCommand = nil;
|
||||
wrapperCommand = [[IJSVGExporterPathInstructionCommand alloc] init];
|
||||
wrapperCommand.instruction = instruction.instruction;
|
||||
wrapperCommand.params = set ?: @[];
|
||||
[pathInstructions addObject:wrapperCommand];
|
||||
}
|
||||
return [self pathStringWithInstructionSet:pathInstructions
|
||||
floatingPointOptions:floatingPointOptions];
|
||||
@@ -210,7 +188,7 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
for (NSInteger i = length; i-- > 0;) {
|
||||
CGFloat d = data[i];
|
||||
CGFloat proposed = IJSVGExporterPathFloatToFixed(d, options.precision);
|
||||
if (proposed != d) {
|
||||
if(proposed != d) {
|
||||
CGFloat rounded = +IJSVGExporterPathFloatToFixed(d, options.precision - 1);
|
||||
data[i] = IJSVGExporterPathFloatToFixed(+fabs(rounded - d), options.precision + 1)
|
||||
>= kIJSVGExporterPathInstructionErrorThreshold
|
||||
@@ -228,22 +206,22 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
char instructionChar = instruction.instruction;
|
||||
NSInteger length = instruction.dataLength;
|
||||
CGFloat* data = instruction.data;
|
||||
if (strchr("mltqsc", instructionChar) != NULL) {
|
||||
if(strchr("mltqsc", instructionChar) != NULL) {
|
||||
for (NSInteger i = length; i--;) {
|
||||
data[i] += instruction.base[i % 2] - relSubPoint[i % 2];
|
||||
}
|
||||
} else if (instructionChar == 'h') {
|
||||
} else if(instructionChar == 'h') {
|
||||
data[0] += instruction.base[0] - relSubPoint[0];
|
||||
} else if (instructionChar == 'v') {
|
||||
} else if(instructionChar == 'v') {
|
||||
data[0] += instruction.base[1] - relSubPoint[1];
|
||||
} else if (instructionChar == 'a') {
|
||||
} else if(instructionChar == 'a') {
|
||||
data[5] += instruction.base[0] - relSubPoint[0];
|
||||
data[5] += instruction.base[1] - relSubPoint[1];
|
||||
}
|
||||
IJSVGExporterPathInstructionRoundData(data, length, floatingPointOptions);
|
||||
if (instructionChar == 'h') {
|
||||
if(instructionChar == 'h') {
|
||||
relSubPoint[0] += data[0];
|
||||
} else if (instructionChar == 'v') {
|
||||
} else if(instructionChar == 'v') {
|
||||
relSubPoint[1] += data[0];
|
||||
} else {
|
||||
relSubPoint[0] += data[length - 2];
|
||||
@@ -258,7 +236,7 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
{
|
||||
IJSVGExporterPathInstruction* prevInstruction = nil;
|
||||
for (IJSVGExporterPathInstruction* instruction in instructions) {
|
||||
if (prevInstruction == nil || instruction.dataLength == 0) {
|
||||
if(prevInstruction == nil || instruction.dataLength == 0) {
|
||||
prevInstruction = instruction;
|
||||
continue;
|
||||
}
|
||||
@@ -269,15 +247,15 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
CGFloat* adata = (CGFloat*)malloc(sizeof(CGFloat) * length);
|
||||
memcpy(adata, data, sizeof(CGFloat) * length);
|
||||
|
||||
if (strchr("mltqsc", instructionChar) != NULL) {
|
||||
if(strchr("mltqsc", instructionChar) != NULL) {
|
||||
for (NSInteger i = length; i--;) {
|
||||
adata[i] += instruction.base[i % 2];
|
||||
}
|
||||
} else if (instructionChar == 'h') {
|
||||
} else if(instructionChar == 'h') {
|
||||
adata[0] += instruction.base[0];
|
||||
} else if (instructionChar == 'v') {
|
||||
} else if(instructionChar == 'v') {
|
||||
adata[0] += instruction.base[1];
|
||||
} else if (instructionChar == 'a') {
|
||||
} else if(instructionChar == 'a') {
|
||||
adata[5] += instruction.base[0];
|
||||
adata[6] += instruction.base[1];
|
||||
}
|
||||
@@ -285,8 +263,8 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
IJSVGExporterPathInstructionRoundData(adata, length, floatingPointOptions);
|
||||
|
||||
IJSVGExporterPathInstruction* ainstruction = nil;
|
||||
ainstruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:instructionChar
|
||||
dataCount:length] autorelease];
|
||||
ainstruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:instructionChar
|
||||
dataCount:length];
|
||||
memcpy(ainstruction.data, adata, sizeof(CGFloat) * length);
|
||||
|
||||
// run these through our default string runner
|
||||
@@ -296,7 +274,11 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
NSString* comp = [self pathStringFromInstructions:@[ ainstruction ]
|
||||
floatingPointOptions:floatingPointOptions];
|
||||
|
||||
if (comp.length < orig.length && !(instructionChar == prevInstruction.instruction && prevInstruction.instruction > 96 && comp.length == orig.length - 1 && data[0] < 0.f && fmod(prevInstruction.data[prevInstruction.dataLength - 1], 1) != 0.f)) {
|
||||
if(comp.length < orig.length && !(instructionChar == prevInstruction.instruction &&
|
||||
prevInstruction.instruction > 96 &&
|
||||
comp.length == orig.length - 1 &&
|
||||
data[0] < 0.f &&
|
||||
fmod(prevInstruction.data[prevInstruction.dataLength - 1], 1) != 0.f)) {
|
||||
instruction.instruction = toupper(instructionChar);
|
||||
memcpy(data, adata, sizeof(CGFloat) * length);
|
||||
}
|
||||
@@ -319,39 +301,45 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions
|
||||
{
|
||||
NSMutableArray<IJSVGExporterPathInstruction*>* nInstructions = nil;
|
||||
nInstructions = [[[NSMutableArray alloc] initWithCapacity:instructions.count] autorelease];
|
||||
nInstructions = [[NSMutableArray alloc] initWithCapacity:instructions.count];
|
||||
IJSVGExporterPathInstruction* lastInstruction = nil;
|
||||
for (IJSVGExporterPathInstruction* instruction in instructions) {
|
||||
lastInstruction = nInstructions.lastObject;
|
||||
if (lastInstruction == nil) {
|
||||
if(lastInstruction == nil) {
|
||||
[nInstructions addObject:instruction];
|
||||
continue;
|
||||
}
|
||||
if (instruction.instruction == 'c') {
|
||||
if (lastInstruction.instruction == 'c' && instruction.data[0] == -(lastInstruction.data[2] - lastInstruction.data[4]) && instruction.data[1] == -(lastInstruction.data[3] - lastInstruction.data[5])) {
|
||||
if(instruction.instruction == 'c') {
|
||||
if(lastInstruction.instruction == 'c' &&
|
||||
instruction.data[0] == -(lastInstruction.data[2] - lastInstruction.data[4]) &&
|
||||
instruction.data[1] == -(lastInstruction.data[3] - lastInstruction.data[5])) {
|
||||
IJSVGExporterPathInstruction* nInstruction = nil;
|
||||
nInstruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'s'
|
||||
dataCount:4] autorelease];
|
||||
nInstruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'s'
|
||||
dataCount:4];
|
||||
nInstruction.data[0] = instruction.data[2];
|
||||
nInstruction.data[1] = instruction.data[3];
|
||||
nInstruction.data[2] = instruction.data[4];
|
||||
nInstruction.data[3] = instruction.data[5];
|
||||
[nInstructions addObject:nInstruction];
|
||||
continue;
|
||||
} else if (lastInstruction.instruction == 's' && instruction.data[0] == -(lastInstruction.data[0] - lastInstruction.data[2]) && instruction.data[1] == -(lastInstruction.data[1] - lastInstruction.data[3])) {
|
||||
} else if(lastInstruction.instruction == 's' &&
|
||||
instruction.data[0] == -(lastInstruction.data[0] - lastInstruction.data[2]) &&
|
||||
instruction.data[1] == -(lastInstruction.data[1] - lastInstruction.data[3])) {
|
||||
IJSVGExporterPathInstruction* nInstruction = nil;
|
||||
nInstruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'s'
|
||||
dataCount:4] autorelease];
|
||||
nInstruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'s'
|
||||
dataCount:4];
|
||||
nInstruction.data[0] = instruction.data[2];
|
||||
nInstruction.data[1] = instruction.data[3];
|
||||
nInstruction.data[2] = instruction.data[4];
|
||||
nInstruction.data[3] = instruction.data[5];
|
||||
[nInstructions addObject:nInstruction];
|
||||
continue;
|
||||
} else if (lastInstruction.instruction != 'c' && lastInstruction.instruction != 's' && instruction.data[0] == 0.f && instruction.data[1] == 0.f) {
|
||||
} else if(lastInstruction.instruction != 'c' &&
|
||||
lastInstruction.instruction != 's' &&
|
||||
instruction.data[0] == 0.f && instruction.data[1] == 0.f) {
|
||||
IJSVGExporterPathInstruction* nInstruction = nil;
|
||||
nInstruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'s'
|
||||
dataCount:4] autorelease];
|
||||
nInstruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'s'
|
||||
dataCount:4];
|
||||
nInstruction.data[0] = instruction.data[2];
|
||||
nInstruction.data[1] = instruction.data[3];
|
||||
nInstruction.data[2] = instruction.data[4];
|
||||
@@ -359,19 +347,23 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
[nInstructions addObject:nInstruction];
|
||||
continue;
|
||||
}
|
||||
} else if (instruction.instruction == 'q') {
|
||||
if (lastInstruction.instruction == 'q' && instruction.data[0] == (lastInstruction.data[2] - lastInstruction.data[0]) && instruction.data[1] == (lastInstruction.data[3] - lastInstruction.data[1])) {
|
||||
} else if(instruction.instruction == 'q') {
|
||||
if(lastInstruction.instruction == 'q' &&
|
||||
instruction.data[0] == (lastInstruction.data[2] - lastInstruction.data[0]) &&
|
||||
instruction.data[1] == (lastInstruction.data[3] - lastInstruction.data[1])) {
|
||||
IJSVGExporterPathInstruction* nInstruction = nil;
|
||||
nInstruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'t'
|
||||
dataCount:2] autorelease];
|
||||
nInstruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'t'
|
||||
dataCount:2];
|
||||
nInstruction.data[0] = instruction.data[2];
|
||||
nInstruction.data[1] = instruction.data[3];
|
||||
[nInstructions addObject:nInstruction];
|
||||
continue;
|
||||
} else if (lastInstruction.instruction == 't' && instruction.data[2] == lastInstruction.data[0] && instruction.data[3] == lastInstruction.data[1]) {
|
||||
} else if(lastInstruction.instruction == 't' &&
|
||||
instruction.data[2] == lastInstruction.data[0] &&
|
||||
instruction.data[3] == lastInstruction.data[1]) {
|
||||
IJSVGExporterPathInstruction* nInstruction = nil;
|
||||
nInstruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'t'
|
||||
dataCount:2] autorelease];
|
||||
nInstruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'t'
|
||||
dataCount:2];
|
||||
nInstruction.data[0] = instruction.data[2];
|
||||
nInstruction.data[1] = instruction.data[3];
|
||||
[nInstructions addObject:nInstruction];
|
||||
@@ -386,128 +378,159 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
+ (void)convertInstructionsToRelativeCoordinates:(NSArray<IJSVGExporterPathInstruction*>*)instructions
|
||||
floatingPointOptions:(IJSVGFloatingPointOptions)floatingPointOptions
|
||||
{
|
||||
CGFloat point[2] = { 0, 0 };
|
||||
CGFloat subpathPoint[2] = { 0, 0 };
|
||||
IJSVGExporterPathInstruction* baseInstruction = nil;
|
||||
IJSVGExporterPathInstruction* prevInstruction = nil;
|
||||
CGFloat start[2] = {0, 0};
|
||||
CGFloat cursor[2] = {0, 0};
|
||||
CGFloat prevCoords[2] = {0, 0};
|
||||
|
||||
NSInteger index = 0;
|
||||
for (IJSVGExporterPathInstruction* anInstruction in instructions) {
|
||||
char instruction = anInstruction.instruction;
|
||||
CGFloat* data = anInstruction.data;
|
||||
NSInteger length = anInstruction.dataLength;
|
||||
|
||||
if (data != NULL) {
|
||||
|
||||
// already relative
|
||||
if (instruction == 'm' || instruction == 'c' || instruction == 's' || instruction == 'l' || instruction == 'q' || instruction == 't' || instruction == 'a') {
|
||||
|
||||
point[0] += data[length - 2];
|
||||
point[1] += data[length - 1];
|
||||
|
||||
if (instruction == 'm') {
|
||||
subpathPoint[0] = point[0];
|
||||
subpathPoint[1] = point[1];
|
||||
|
||||
baseInstruction = anInstruction;
|
||||
}
|
||||
|
||||
} else if (instruction == 'h') {
|
||||
point[0] += data[0];
|
||||
} else if (instruction == 'v') {
|
||||
point[1] += data[0];
|
||||
CGFloat* base = anInstruction.base;
|
||||
CGFloat* coords = anInstruction.coords;
|
||||
|
||||
switch(instruction) {
|
||||
case 'm': {
|
||||
cursor[0] += data[0];
|
||||
cursor[1] += data[1];
|
||||
start[0] = cursor[0];
|
||||
start[1] = cursor[1];
|
||||
break;
|
||||
}
|
||||
|
||||
// convert absolute to relative
|
||||
if (instruction == 'M') {
|
||||
if (index > 0) {
|
||||
case 'M': {
|
||||
if(index != 0) {
|
||||
instruction = 'm';
|
||||
}
|
||||
|
||||
data[0] -= point[0];
|
||||
data[1] -= point[1];
|
||||
|
||||
subpathPoint[0] = point[0] += data[0];
|
||||
subpathPoint[1] = point[1] += data[1];
|
||||
|
||||
baseInstruction = anInstruction;
|
||||
} else if (instruction == 'L' || instruction == 'T') {
|
||||
instruction = tolower(instruction);
|
||||
|
||||
data[0] -= point[0];
|
||||
data[1] -= point[1];
|
||||
|
||||
point[0] += data[0];
|
||||
point[1] += data[1];
|
||||
} else if (instruction == 'C') {
|
||||
instruction = 'c';
|
||||
|
||||
data[0] -= point[0];
|
||||
data[1] -= point[1];
|
||||
data[2] -= point[0];
|
||||
data[3] -= point[1];
|
||||
data[4] -= point[0];
|
||||
data[5] -= point[1];
|
||||
|
||||
point[0] += data[4];
|
||||
point[1] += data[5];
|
||||
} else if (instruction == 'S' || instruction == 'Q') {
|
||||
instruction = tolower(instruction);
|
||||
|
||||
data[0] -= point[0];
|
||||
data[1] -= point[1];
|
||||
data[2] -= point[0];
|
||||
data[3] -= point[1];
|
||||
|
||||
point[0] += data[2];
|
||||
point[1] += data[3];
|
||||
} else if (instruction == 'A') {
|
||||
instruction = 'a';
|
||||
|
||||
data[5] -= point[0];
|
||||
data[6] -= point[1];
|
||||
|
||||
point[0] += data[5];
|
||||
point[1] += data[6];
|
||||
} else if (instruction == 'H') {
|
||||
data[0] -= cursor[0];
|
||||
data[1] -= cursor[1];
|
||||
cursor[0] += data[0];
|
||||
cursor[1] += data[1];
|
||||
start[0] = cursor[0];
|
||||
start[1] = cursor[1];
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
cursor[0] += data[0];
|
||||
cursor[1] += data[1];
|
||||
break;
|
||||
}
|
||||
case 'L': {
|
||||
instruction = 'l';
|
||||
data[0] -= cursor[0];
|
||||
data[1] -= cursor[1];
|
||||
cursor[0] += data[0];
|
||||
cursor[1] += data[1];
|
||||
break;
|
||||
}
|
||||
case 'h': {
|
||||
cursor[0] += data[0];
|
||||
break;
|
||||
}
|
||||
case 'H': {
|
||||
instruction = 'h';
|
||||
|
||||
data[0] -= point[0];
|
||||
point[0] += data[0];
|
||||
} else if (instruction == 'V') {
|
||||
data[0] -= cursor[0];
|
||||
cursor[0] += data[0];
|
||||
break;
|
||||
}
|
||||
case 'v': {
|
||||
cursor[1] += data[0];
|
||||
break;
|
||||
}
|
||||
case 'V': {
|
||||
instruction = 'v';
|
||||
|
||||
data[0] -= point[1];
|
||||
point[1] += data[0];
|
||||
data[0] -= cursor[1];
|
||||
cursor[1] += data[0];
|
||||
break;
|
||||
}
|
||||
|
||||
// reset the instruction
|
||||
anInstruction.instruction = instruction;
|
||||
CGFloat* coords = anInstruction.coords;
|
||||
coords[0] = point[0];
|
||||
coords[1] = point[1];
|
||||
|
||||
} else if (instruction == 'Z' || instruction == 'z') {
|
||||
if (baseInstruction != nil) {
|
||||
CGFloat* coords = anInstruction.coords;
|
||||
coords[0] = baseInstruction.coords[0];
|
||||
coords[1] = baseInstruction.coords[1];
|
||||
case 'c': {
|
||||
cursor[0] += data[4];
|
||||
cursor[1] += data[5];
|
||||
break;
|
||||
}
|
||||
case 'C': {
|
||||
instruction = 'c';
|
||||
data[0] -= cursor[0];
|
||||
data[1] -= cursor[1];
|
||||
data[2] -= cursor[0];
|
||||
data[3] -= cursor[1];
|
||||
data[4] -= cursor[0];
|
||||
data[5] -= cursor[1];
|
||||
cursor[0] += data[4];
|
||||
cursor[1] += data[5];
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
cursor[0] += data[2];
|
||||
cursor[1] += data[3];
|
||||
break;
|
||||
}
|
||||
case 'S': {
|
||||
instruction = 's';
|
||||
data[0] -= cursor[0];
|
||||
data[1] -= cursor[1];
|
||||
data[2] -= cursor[0];
|
||||
data[3] -= cursor[1];
|
||||
cursor[0] += data[2];
|
||||
cursor[1] += data[3];
|
||||
break;
|
||||
}
|
||||
case 'q': {
|
||||
cursor[0] += data[2];
|
||||
cursor[1] += data[3];
|
||||
break;
|
||||
}
|
||||
case 'Q': {
|
||||
instruction = 'q';
|
||||
data[0] -= cursor[0];
|
||||
data[1] -= cursor[1];
|
||||
data[2] -= cursor[0];
|
||||
data[3] -= cursor[1];
|
||||
cursor[0] += data[2];
|
||||
cursor[1] += data[3];
|
||||
break;
|
||||
}
|
||||
case 't': {
|
||||
cursor[0] += data[0];
|
||||
cursor[1] += data[1];
|
||||
break;
|
||||
}
|
||||
case 'T': {
|
||||
instruction = 't';
|
||||
data[0] -= cursor[0];
|
||||
data[1] -= cursor[1];
|
||||
cursor[0] += data[0];
|
||||
cursor[1] += data[1];
|
||||
break;
|
||||
}
|
||||
case 'a': {
|
||||
cursor[0] += data[5];
|
||||
cursor[1] += data[6];
|
||||
break;
|
||||
}
|
||||
case 'A': {
|
||||
instruction = 'a';
|
||||
data[5] -= cursor[0];
|
||||
data[6] -= cursor[1];
|
||||
cursor[0] += data[5];
|
||||
cursor[1] += data[6];
|
||||
break;
|
||||
}
|
||||
case 'Z':
|
||||
case 'z': {
|
||||
cursor[0] = start[0];
|
||||
cursor[1] = start[1];
|
||||
break;
|
||||
}
|
||||
point[0] = subpathPoint[0];
|
||||
point[1] = subpathPoint[1];
|
||||
}
|
||||
|
||||
CGFloat* base = anInstruction.base;
|
||||
if (prevInstruction != nil) {
|
||||
base[0] = prevInstruction.coords[0];
|
||||
base[1] = prevInstruction.coords[1];
|
||||
} else {
|
||||
base[0] = 0.f;
|
||||
base[1] = 0.f;
|
||||
}
|
||||
|
||||
// increment index
|
||||
prevInstruction = anInstruction;
|
||||
// set the instruction back
|
||||
anInstruction.instruction = instruction;
|
||||
base[0] = prevCoords[0];
|
||||
base[1] = prevCoords[1];
|
||||
coords[0] = cursor[0];
|
||||
coords[1] = cursor[1];
|
||||
prevCoords[0] = cursor[0];
|
||||
prevCoords[1] = cursor[1];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
@@ -518,7 +541,7 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
|
||||
// keep track of the current point
|
||||
__block CGPoint currentPoint = CGPointZero;
|
||||
NSMutableArray* instructions = [[[NSMutableArray alloc] init] autorelease];
|
||||
NSMutableArray* instructions = [[NSMutableArray alloc] init];
|
||||
|
||||
// create the path callback
|
||||
IJSVGCGPathHandler callback = ^(const CGPathElement* pathElement) {
|
||||
@@ -528,8 +551,8 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
|
||||
case kCGPathElementMoveToPoint: {
|
||||
// move to command
|
||||
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'M'
|
||||
dataCount:2] autorelease];
|
||||
instruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'M'
|
||||
dataCount:2];
|
||||
CGPoint point = pathElement->points[0];
|
||||
instruction.data[0] = point.x;
|
||||
instruction.data[1] = point.y;
|
||||
@@ -542,17 +565,17 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
case kCGPathElementAddLineToPoint: {
|
||||
// line to command
|
||||
CGPoint point = pathElement->points[0];
|
||||
if (point.x == currentPoint.x) {
|
||||
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'V'
|
||||
dataCount:1] autorelease];
|
||||
if(point.x == currentPoint.x) {
|
||||
instruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'V'
|
||||
dataCount:1];
|
||||
instruction.data[0] = point.y;
|
||||
} else if (point.y == currentPoint.y) {
|
||||
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'H'
|
||||
dataCount:1] autorelease];
|
||||
} else if(point.y == currentPoint.y) {
|
||||
instruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'H'
|
||||
dataCount:1];
|
||||
instruction.data[0] = point.x;
|
||||
} else {
|
||||
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'L'
|
||||
dataCount:2] autorelease];
|
||||
instruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'L'
|
||||
dataCount:2];
|
||||
instruction.data[0] = point.x;
|
||||
instruction.data[1] = point.y;
|
||||
}
|
||||
@@ -566,8 +589,8 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
// quad curve to command
|
||||
CGPoint controlPoint = pathElement->points[0];
|
||||
CGPoint point = pathElement->points[1];
|
||||
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'Q'
|
||||
dataCount:4] autorelease];
|
||||
instruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'Q'
|
||||
dataCount:4];
|
||||
instruction.data[0] = controlPoint.x;
|
||||
instruction.data[1] = controlPoint.y;
|
||||
instruction.data[2] = point.x;
|
||||
@@ -585,8 +608,8 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
CGPoint point = pathElement->points[2];
|
||||
|
||||
currentPoint = point;
|
||||
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'C'
|
||||
dataCount:6] autorelease];
|
||||
instruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'C'
|
||||
dataCount:6];
|
||||
instruction.data[0] = controlPoint1.x;
|
||||
instruction.data[1] = controlPoint1.y;
|
||||
instruction.data[2] = controlPoint2.x;
|
||||
@@ -600,8 +623,8 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
|
||||
case kCGPathElementCloseSubpath: {
|
||||
// close command
|
||||
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'Z'
|
||||
dataCount:0] autorelease];
|
||||
instruction = [[IJSVGExporterPathInstruction alloc] initWithInstruction:'Z'
|
||||
dataCount:0];
|
||||
[instructions addObject:instruction];
|
||||
break;
|
||||
}
|
||||
@@ -613,11 +636,11 @@ void IJSVGExporterPathInstructionRoundData(CGFloat* data, NSInteger length,
|
||||
|
||||
// remove last instruction if it was Z -> M
|
||||
IJSVGExporterPathInstruction* lastInstruction = instructions.lastObject;
|
||||
if (lastInstruction.instruction == 'M' || lastInstruction.instruction == 'm') {
|
||||
if (instructions.count >= 2) {
|
||||
if(lastInstruction.instruction == 'M' || lastInstruction.instruction == 'm') {
|
||||
if(instructions.count >= 2) {
|
||||
NSInteger index = [instructions indexOfObject:lastInstruction] - 1;
|
||||
IJSVGExporterPathInstruction* prevInstruction = instructions[index];
|
||||
if (prevInstruction.instruction == 'z' || prevInstruction.instruction == 'Z') {
|
||||
if(prevInstruction.instruction == 'z' || prevInstruction.instruction == 'Z') {
|
||||
[instructions removeLastObject];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// IJSVGBasicLayer.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 19/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
|
||||
@interface IJSVGBasicLayer : CALayer <IJSVGBasicLayer>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// IJSVGBasicLayer.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 19/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGBasicLayer.h>
|
||||
|
||||
@implementation IJSVGBasicLayer
|
||||
|
||||
@synthesize backingScaleFactor;
|
||||
@synthesize requiresBackingScale;
|
||||
@synthesize renderQuality;
|
||||
@synthesize debugLayers;
|
||||
|
||||
- (id<CAAction>)actionForKey:(NSString*)event
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (void)performRenderInContext:(CGContextRef)ctx
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// IJSVGFilterLayer.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 19/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
#import <IJSVG/IJSVGFilter.h>
|
||||
#import <IJSVG/IJSVGBasicLayer.h>
|
||||
|
||||
@interface IJSVGFilterLayer : IJSVGLayer {
|
||||
|
||||
@private
|
||||
IJSVGBasicLayer* _hostingLayer;
|
||||
CGImageRef _image;
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) CALayer<IJSVGDrawableLayer>* sublayer;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// IJSVGFilterLayer.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 19/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGFilterLayer.h>
|
||||
#import <IJSVG/IJSVGTransform.h>
|
||||
|
||||
@implementation IJSVGFilterLayer
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)CGImageRelease(_image), _image = nil;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if((self = [super init]) != nil) {
|
||||
_hostingLayer = [IJSVGBasicLayer layer];
|
||||
[self addSublayer:_hostingLayer];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)requiresBackingScale
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)setBackingScaleFactor:(CGFloat)backingScaleFactor
|
||||
{
|
||||
// we are responsible for recursively calling the sublayer
|
||||
// with the new backing scale factor
|
||||
[IJSVGLayer setBackingScaleFactor:backingScaleFactor
|
||||
renderQuality:self.renderQuality
|
||||
recursivelyToLayer:_sublayer];
|
||||
|
||||
BOOL needsChange = self.backingScaleFactor != backingScaleFactor;
|
||||
[super setBackingScaleFactor:backingScaleFactor];
|
||||
if(needsChange == YES) {
|
||||
[self updateImage];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateImage
|
||||
{
|
||||
if(_image != nil) {
|
||||
(void)CGImageRelease(_image), _image = nil;
|
||||
}
|
||||
_image = [self.filter newImageByApplyFilterToLayer:_sublayer
|
||||
scale:self.backingScaleFactor];
|
||||
}
|
||||
|
||||
- (void)layoutSublayers
|
||||
{
|
||||
CGRect frame = _sublayer.innerBoundingBox;
|
||||
_hostingLayer.frame = frame;
|
||||
_hostingLayer.contents = (__bridge id)_image;
|
||||
}
|
||||
|
||||
- (NSArray<CALayer<IJSVGBasicLayer>*>*)debugLayers
|
||||
{
|
||||
return @[_sublayer];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -14,7 +14,7 @@
|
||||
@interface IJSVGGradientLayer : IJSVGLayer {
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) IJSVGGradient* gradient;
|
||||
@property (nonatomic, strong) IJSVGGradient* gradient;
|
||||
@property (nonatomic, assign) CGRect viewBox;
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,38 +6,24 @@
|
||||
// Copyright © 2016 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGGradientLayer.h"
|
||||
#import <IJSVG/IJSVGGradientLayer.h>
|
||||
#import <IJSVG/IJSVGRootLayer.h>
|
||||
|
||||
@implementation IJSVGGradientLayer
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_gradient release]), _gradient = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
- (BOOL)requiresBackingScale
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)setGradient:(IJSVGGradient*)newGradient
|
||||
{
|
||||
if (_gradient != nil) {
|
||||
(void)([_gradient release]), _gradient = nil;
|
||||
}
|
||||
_gradient = [newGradient retain];
|
||||
_gradient = newGradient;
|
||||
|
||||
// lets check its alpha properties on the colors
|
||||
BOOL hasAlphaChannel = NO;
|
||||
NSInteger stops = _gradient.gradient.numberOfColorStops;
|
||||
for (NSInteger i = 0; i < stops; i++) {
|
||||
NSColor* color = nil;
|
||||
[_gradient.gradient getColor:&color
|
||||
location:NULL
|
||||
atIndex:i];
|
||||
if (color.alphaComponent != 1.f) {
|
||||
for (NSColor* color in newGradient.colors) {
|
||||
if(color.alphaComponent != 1.f) {
|
||||
hasAlphaChannel = YES;
|
||||
break;
|
||||
}
|
||||
@@ -47,7 +33,7 @@
|
||||
|
||||
- (void)setOpacity:(float)opacity
|
||||
{
|
||||
if (opacity != 1.f) {
|
||||
if(opacity != 1.f) {
|
||||
self.opaque = NO;
|
||||
}
|
||||
[super setOpacity:opacity];
|
||||
@@ -56,17 +42,17 @@
|
||||
- (void)setBackingScaleFactor:(CGFloat)backingScaleFactor
|
||||
{
|
||||
switch (self.renderQuality) {
|
||||
case kIJSVGRenderQualityOptimized: {
|
||||
backingScaleFactor = (backingScaleFactor * .35f);
|
||||
break;
|
||||
}
|
||||
case kIJSVGRenderQualityLow: {
|
||||
backingScaleFactor = (backingScaleFactor * .05f);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
case kIJSVGRenderQualityOptimized: {
|
||||
backingScaleFactor = (backingScaleFactor * .35f);
|
||||
break;
|
||||
}
|
||||
case kIJSVGRenderQualityLow: {
|
||||
backingScaleFactor = (backingScaleFactor * .05f);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
[super setBackingScaleFactor:backingScaleFactor];
|
||||
}
|
||||
@@ -81,28 +67,41 @@
|
||||
[super drawInContext:ctx];
|
||||
|
||||
// nothing to do :(
|
||||
if (self.gradient == nil) {
|
||||
if(self.gradient == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
// draw the gradient
|
||||
// perform the draw
|
||||
CGRect bounds = CGRectZero;
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
CALayer<IJSVGDrawableLayer>* layer = (CALayer<IJSVGDrawableLayer>*)self.referencingLayer;
|
||||
CGRect objectRect = layer.boundingBox;
|
||||
CGRect objectFrame = layer.frame;
|
||||
CGAffineTransform affine = [IJSVGLayer absoluteTransformForLayer:layer];
|
||||
affine = CGAffineTransformTranslate(affine,
|
||||
-CGRectGetMinX(objectFrame),
|
||||
-CGRectGetMinY(objectFrame));
|
||||
CGContextSaveGState(ctx);
|
||||
if(self.gradient.units == IJSVGUnitUserSpaceOnUse) {
|
||||
IJSVGRootLayer* rootNode = (IJSVGRootLayer*)[IJSVGLayer rootLayerForLayer:self];
|
||||
bounds = [rootNode.viewBox computeValue:CGSizeZero];
|
||||
transform = [IJSVGLayer userSpaceTransformForLayer:layer];
|
||||
} else {
|
||||
bounds = IJSVGLayerGetBoundingBoxBounds(layer);
|
||||
}
|
||||
|
||||
IJSVGRootLayer* rootNode = (IJSVGRootLayer*)[IJSVGLayer rootLayerForLayer:self];
|
||||
CGRect bounds = [rootNode.viewBox computeValue:CGSizeZero];
|
||||
// its possible that this layer is shifted inwards due to a stroke on the
|
||||
// parent layer
|
||||
transform = CGAffineTransformConcat(transform, [IJSVGLayer userSpaceTransformForLayer:self]);
|
||||
|
||||
[self.gradient drawInContextRef:ctx
|
||||
objectRect:objectRect
|
||||
absoluteTransform:affine
|
||||
viewPort:bounds];
|
||||
CGContextRestoreGState(ctx);
|
||||
bounds:bounds
|
||||
transform:transform];
|
||||
}
|
||||
|
||||
- (IJSVGTraitedColorStorage*)colors
|
||||
{
|
||||
IJSVGTraitedColorStorage* list = [[IJSVGTraitedColorStorage alloc] init];
|
||||
for(NSColor* color in self.gradient.colors) {
|
||||
IJSVGTraitedColor* traited = nil;
|
||||
traited = [IJSVGTraitedColor colorWithColor:color
|
||||
traits:IJSVGColorUsageTraitNone];
|
||||
[list addColor:traited];
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -8,13 +8,15 @@
|
||||
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
#import <IJSVG/IJSVGShapeLayer.h>
|
||||
#import <IJSVG/IJSVGUnitRect.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
@interface IJSVGGroupLayer : IJSVGLayer {
|
||||
@interface IJSVGGroupLayer : IJSVGLayer <IJSVGMaskingLayer> {
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) IJSVGUnitRect* viewBox;
|
||||
@property (nonatomic, strong) IJSVGUnitSize* intrinsicSize;
|
||||
@property (nonatomic, strong) IJSVGUnitRect* viewBox;
|
||||
@property (nonatomic, assign) IJSVGViewBoxAlignment viewBoxAlignment;
|
||||
@property (nonatomic, assign) IJSVGViewBoxMeetOrSlice viewBoxMeetOrSlice;
|
||||
|
||||
|
||||
@@ -6,17 +6,16 @@
|
||||
// Copyright © 2017 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGGroupLayer.h"
|
||||
#import "IJSVGViewBox.h"
|
||||
#import "IJSVGUnitRect.h"
|
||||
#import "IJSVGLayer.h"
|
||||
#import <IJSVG/IJSVGGroupLayer.h>
|
||||
#import <IJSVG/IJSVGViewBox.h>
|
||||
#import <IJSVG/IJSVGUnitRect.h>
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
|
||||
@implementation IJSVGGroupLayer
|
||||
|
||||
- (void)dealloc
|
||||
- (CGRect)innerBoundingBox
|
||||
{
|
||||
(void)[_viewBox release], _viewBox = nil;
|
||||
[super dealloc];
|
||||
return self.outerBoundingBox;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,16 +9,15 @@
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
#import <IJSVG/IJSVGImage.h>
|
||||
#import <IJSVG/IJSVGTransformLayer.h>
|
||||
#import <IJSVG/IJSVGTileLayer.h>
|
||||
#import <IJSVG/IJSVGBasicLayer.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
@interface IJSVGImageLayer : IJSVGLayer {
|
||||
|
||||
@private
|
||||
IJSVGLayer* _imageLayer;
|
||||
@interface IJSVGImageLayer : IJSVGTileLayer {
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) IJSVGImage* image;
|
||||
@property (nonatomic, strong) IJSVGImage* image;
|
||||
|
||||
- (id)initWithImage:(IJSVGImage*)image;
|
||||
|
||||
|
||||
@@ -6,48 +6,43 @@
|
||||
// Copyright © 2017 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGImageLayer.h"
|
||||
#import <IJSVG/IJSVGImageLayer.h>
|
||||
|
||||
@implementation IJSVGImageLayer
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)[_image release], _image = nil;
|
||||
(void)[_imageLayer release], _imageLayer = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)initWithImage:(IJSVGImage*)image
|
||||
{
|
||||
if((self = [super init]) != nil) {
|
||||
_image = image.retain;
|
||||
self.image = image;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
- (BOOL)requiresBackingScale
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)layoutSublayers
|
||||
- (void)setImage:(IJSVGImage *)image
|
||||
{
|
||||
[super layoutSublayers];
|
||||
[self reloadContent];
|
||||
_image = image;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)reloadContent
|
||||
- (void)drawInContext:(CGContextRef)ctx
|
||||
{
|
||||
if(_imageLayer == nil) {
|
||||
_imageLayer = [IJSVGLayer layer].retain;
|
||||
_imageLayer.contentsGravity = kCAGravityResize;
|
||||
_imageLayer.affineTransform = CGAffineTransformMakeScale(1.f, -1.f);
|
||||
_imageLayer.contents = (id)_image.CGImage;
|
||||
[self addSublayer:_imageLayer];
|
||||
}
|
||||
|
||||
_imageLayer.frame = self.bounds;
|
||||
CGImageRef image = _image.CGImage;
|
||||
CGRect imageDrawRect = _image.bounds;
|
||||
CGRect currentBounds = self.bounds;
|
||||
IJSVGViewBoxDrawingBlock drawBlock = ^(CGFloat scale[]) {
|
||||
// image will be upside down, so just translate it back on itself
|
||||
CGContextConcatCTM(ctx, CGAffineTransformMakeScale(1.f, -1.f));
|
||||
CGContextTranslateCTM(ctx, 0.f, -CGRectGetHeight(imageDrawRect));
|
||||
CGContextDrawImage(ctx, imageDrawRect, image);
|
||||
};
|
||||
IJSVGContextDrawViewBox(ctx, imageDrawRect, currentBounds,
|
||||
_image.viewBoxAlignment,
|
||||
_image.viewBoxMeetOrSlice, drawBlock);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -16,6 +16,19 @@
|
||||
@class IJSVGStrokeLayer;
|
||||
@class IJSVGGroupLayer;
|
||||
@class IJSVGLayer;
|
||||
@class IJSVGFilter;
|
||||
@class IJSVGTraitedColorStorage;
|
||||
|
||||
typedef NS_OPTIONS(NSUInteger, IJSVGLayerTraits) {
|
||||
IJSVGLayerTraitNone = 0,
|
||||
IJSVGLayerTraitFilled = 1 << 1,
|
||||
IJSVGLayerTraitStroked = 1 << 2
|
||||
};
|
||||
|
||||
typedef NS_OPTIONS(NSUInteger, IJSVGLayerDrawingOptions) {
|
||||
IJSVGLayerDrawingOptionNone = 0,
|
||||
IJSVGLayerDrawingOptionIgnoreClipping = 1 << 1
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, IJSVGLayerFillType) {
|
||||
IJSVGLayerFillTypeColor,
|
||||
@@ -24,8 +37,14 @@ typedef NS_ENUM(NSUInteger, IJSVGLayerFillType) {
|
||||
IJSVGLayerFillTypeUnknown
|
||||
};
|
||||
|
||||
typedef NS_OPTIONS(NSUInteger, IJSVGLayerTraits) {
|
||||
IJSVGLayerTraitGroup
|
||||
typedef NS_ENUM(NSUInteger, IJSVGLayerUsageType) {
|
||||
IJSVGLayerUsageTypeFillGeneric,
|
||||
IJSVGLayerUsageTypeFillPattern,
|
||||
IJSVGLayerUsageTypeFillGradient,
|
||||
IJSVGLayerUsageTypeStrokeGeneric,
|
||||
IJSVGLayerUsageTypeStrokePattern,
|
||||
IJSVGLayerUsageTypeStrokeGradient,
|
||||
IJSVGLayerUsageTypeStroke
|
||||
};
|
||||
|
||||
@protocol IJSVGPathableLayer <NSObject>
|
||||
@@ -35,92 +54,126 @@ typedef NS_OPTIONS(NSUInteger, IJSVGLayerTraits) {
|
||||
|
||||
@end
|
||||
|
||||
@protocol IJSVGDrawableLayer <NSObject>
|
||||
@protocol IJSVGBasicLayer <NSObject>
|
||||
|
||||
@required
|
||||
@property (nonatomic, assign) CGBlendMode blendingMode;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* clipLayer;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* maskLayer;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule clipRule;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule fillRule;
|
||||
@property (nonatomic, readonly) CGPoint absoluteOrigin;
|
||||
@property (nonatomic, assign) IJSVGRenderQuality renderQuality;
|
||||
@property (nonatomic, assign) CGFloat backingScaleFactor;
|
||||
@property (nonatomic, readonly) BOOL requiresBackingScaleHelp;
|
||||
@property (nonatomic, readonly) CALayer<IJSVGDrawableLayer>* rootLayer;
|
||||
@property (nonatomic, readonly) CGRect absoluteFrame;
|
||||
@property (nonatomic, assign) CGRect boundingBox;
|
||||
@property (nonatomic, readonly) CGRect strokeBoundingBox;
|
||||
@property (nonatomic, readonly) CGRect boundingBoxBounds;
|
||||
@property (nonatomic, assign) CGRect outerBoundingBox;
|
||||
@property (nonatomic, assign) CALayer<IJSVGDrawableLayer>* referencingLayer;
|
||||
@property (nonatomic, readonly) NSArray<CALayer<IJSVGDrawableLayer>*>* debugLayers;
|
||||
|
||||
- (void)performRenderInContext:(CGContextRef)ctx;
|
||||
@property (nonatomic, readonly) BOOL requiresBackingScale;
|
||||
@property (nonatomic, assign) IJSVGRenderQuality renderQuality;
|
||||
@property (nonatomic, readonly) NSArray<CALayer<IJSVGBasicLayer>*>* debugLayers;
|
||||
|
||||
@end
|
||||
|
||||
@interface IJSVGLayer : CALayer <IJSVGDrawableLayer> {
|
||||
@protocol IJSVGMaskingLayer <NSObject>
|
||||
|
||||
@required
|
||||
@property (nonatomic, assign) CGRect maskingBoundingBox;
|
||||
@property (nonatomic, assign) CGRect maskingClippingRect;
|
||||
|
||||
@end
|
||||
|
||||
@protocol IJSVGClippingLayer <NSObject>
|
||||
|
||||
@required
|
||||
@property (nonatomic, assign) CGRect clippingBoundingBox;
|
||||
@property (nonatomic, assign) CGAffineTransform clippingTransform;
|
||||
@property (nonatomic, assign) CGPathRef clipPath;
|
||||
@property (nonatomic, assign) CGAffineTransform clipPathTransform;
|
||||
|
||||
@end
|
||||
|
||||
@protocol IJSVGDrawableLayer <NSObject, IJSVGBasicLayer, IJSVGMaskingLayer, IJSVGClippingLayer>
|
||||
|
||||
@required
|
||||
@property (nonatomic, readonly) BOOL treatImplicitOriginAsTransform;
|
||||
@property (nonatomic, assign) CGBlendMode blendingMode;
|
||||
@property (nonatomic, strong) NSArray<CALayer<IJSVGDrawableLayer>*>* clipLayers;
|
||||
@property (nonatomic, strong) CALayer<IJSVGDrawableLayer>* maskLayer;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule clipRule;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule fillRule;
|
||||
@property (nonatomic, readonly) CGPoint absoluteOrigin;
|
||||
@property (nonatomic, readonly) CGRect absoluteFrame;
|
||||
@property (nonatomic, assign) CGRect boundingBox;
|
||||
@property (nonatomic, assign) CGRect outerBoundingBox;
|
||||
@property (nonatomic, readonly) CGRect innerBoundingBox;
|
||||
@property (nonatomic, weak) CALayer<IJSVGDrawableLayer>* referencingLayer;
|
||||
@property (nonatomic, strong) IJSVGFilter* filter;
|
||||
@property (nonatomic, readonly) IJSVGLayerTraits layerTraits;
|
||||
@property (nonatomic, readonly) NSMapTable<NSNumber*, CALayer<IJSVGDrawableLayer>*>* layerUsageMapTable;
|
||||
@property (nonatomic, readonly) IJSVGTraitedColorStorage* colors;
|
||||
|
||||
- (void)performRenderInContext:(CGContextRef)ctx;
|
||||
|
||||
- (void)setLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
forUsageType:(IJSVGLayerUsageType)type;
|
||||
- (CALayer<IJSVGDrawableLayer>*)layerForUsageType:(IJSVGLayerUsageType)type;
|
||||
- (CALayer<IJSVGDrawableLayer>*)strokeLayer:(IJSVGLayerUsageType*)usageType;
|
||||
|
||||
- (void)addTraits:(IJSVGLayerTraits)traits;
|
||||
- (void)removeTraits:(IJSVGLayerTraits)traits;
|
||||
- (BOOL)matchesTraits:(IJSVGLayerTraits)traits;
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)firstSublayerOfClass:(Class)aClass;
|
||||
|
||||
@end
|
||||
|
||||
CGRect IJSVGLayerGetBoundingBoxBounds(CALayer<IJSVGDrawableLayer>* drawableLayer);
|
||||
NSMapTable<NSNumber*, CALayer<IJSVGDrawableLayer>*>* IJSVGLayerDefaultUsageMapTable(void);
|
||||
|
||||
@interface IJSVGLayer : CALayer <IJSVGDrawableLayer, IJSVGMaskingLayer> {
|
||||
|
||||
@private
|
||||
IJSVGLayer* _maskingLayer;
|
||||
NSMapTable<NSNumber*, CALayer<IJSVGDrawableLayer>*>* _layerUsageMapTable;
|
||||
}
|
||||
|
||||
@property (nonatomic, assign) IJSVGGradientLayer* gradientFillLayer;
|
||||
@property (nonatomic, assign) IJSVGPatternLayer* patternFillLayer;
|
||||
@property (nonatomic, assign) IJSVGStrokeLayer* strokeLayer;
|
||||
@property (nonatomic, assign) IJSVGGradientLayer* gradientStrokeLayer;
|
||||
@property (nonatomic, assign) IJSVGPatternLayer* patternStrokeLayer;
|
||||
@property (nonatomic, readonly) BOOL requiresBackingScaleHelp;
|
||||
@property (nonatomic, assign) CGFloat backingScaleFactor;
|
||||
@property (nonatomic, assign) IJSVGRenderQuality renderQuality;
|
||||
@property (nonatomic, assign) CGBlendMode blendingMode;
|
||||
@property (nonatomic, assign) CGPoint absoluteOrigin;
|
||||
@property (nonatomic, assign) BOOL convertMasksToPaths;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* clipLayer;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule clipRule;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule fillRule;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* maskLayer;
|
||||
@property (nonatomic, readonly) CALayer<IJSVGDrawableLayer>* rootLayer;
|
||||
@property (nonatomic, readonly) CGRect absoluteFrame;
|
||||
@property (nonatomic, assign) CGRect boundingBox;
|
||||
@property (nonatomic, readonly) CGRect boundingBoxBounds;
|
||||
@property (nonatomic, readonly) CGRect strokeBoundingBox;
|
||||
@property (nonatomic, assign) CGRect outerBoundingBox;
|
||||
@property (nonatomic, readonly) CGRect outerBoundingBoxBounds;
|
||||
@property (nonatomic, assign) CALayer<IJSVGDrawableLayer>* referencingLayer;
|
||||
|
||||
+ (IJSVGLayerFillType)fillTypeForFill:(id)fill;
|
||||
|
||||
+ (NSArray*)deepestSublayersOfLayer:(CALayer*)layer;
|
||||
+ (void)recursivelyWalkLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
withBlock:(void (^)(CALayer<IJSVGDrawableLayer>* layer, BOOL* stop))block;
|
||||
+ (void)recursivelyWalkLayer:(CALayer<IJSVGBasicLayer>*)layer
|
||||
withBlock:(void (^)(CALayer<IJSVGBasicLayer>* layer, BOOL* stop))block;
|
||||
|
||||
+ (CALayer<IJSVGDrawableLayer>*)firstSublayerOfClass:(Class)aClass
|
||||
fromLayer:(CALayer<IJSVGDrawableLayer>*)layer;
|
||||
|
||||
+ (void)setBackingScaleFactor:(CGFloat)scale
|
||||
renderQuality:(IJSVGRenderQuality)quality
|
||||
recursivelyToLayer:(CALayer<IJSVGDrawableLayer>*)layer;
|
||||
|
||||
- (void)applySublayerMaskToContext:(CGContextRef)context
|
||||
forSublayer:(IJSVGLayer*)sublayer
|
||||
withOffset:(CGPoint)offset;
|
||||
|
||||
+ (CGImageRef)newMaskImageForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
options:(IJSVGLayerDrawingOptions)options
|
||||
scale:(CGFloat)scale;
|
||||
|
||||
+ (CGImageRef)newImageForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
options:(IJSVGLayerDrawingOptions)options
|
||||
colorSpace:(CGColorSpaceRef)colorSpace
|
||||
bitmapInfo:(uint32_t)bitmapInfo
|
||||
scale:(CGFloat)scale;
|
||||
|
||||
+ (CGImageRef)newImageWithSize:(CGSize)size
|
||||
drawBlock:(void (^)(CGContextRef context))drawBlock
|
||||
colorSpace:(CGColorSpaceRef)colorSpace
|
||||
bitmapInfo:(uint32_t)bitmapInfo
|
||||
scale:(CGFloat)scale;
|
||||
|
||||
+ (void)renderLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx;
|
||||
inContext:(CGContextRef)ctx
|
||||
options:(IJSVGLayerDrawingOptions)options;
|
||||
|
||||
+ (void)applyBlendingMode:(CGBlendMode)blendMode
|
||||
toContext:(CGContextRef)ctx
|
||||
drawingBlock:(dispatch_block_t)drawingBlock;
|
||||
|
||||
+ (void)clipContextWithClip:(CALayer<IJSVGDrawableLayer>*)clipLayer
|
||||
toLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx
|
||||
drawingBlock:(dispatch_block_t)drawingBlock;
|
||||
+ (void)clipContextWithClipLayers:(NSArray<CALayer<IJSVGDrawableLayer>*>*)clipLayers
|
||||
toLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx
|
||||
drawingBlock:(dispatch_block_t)drawingBlock;
|
||||
|
||||
+ (void)clipContextWithMask:(CALayer<IJSVGDrawableLayer>*)maskLayer
|
||||
+ (void)clipContextWithMask:(CALayer<IJSVGMaskingLayer>*)maskLayer
|
||||
toLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)context
|
||||
drawingBlock:(dispatch_block_t)drawingBlock;
|
||||
@@ -129,6 +182,9 @@ typedef NS_OPTIONS(NSUInteger, IJSVGLayerTraits) {
|
||||
+ (CGAffineTransform)absoluteTransformForLayer:(CALayer*)layer;
|
||||
+ (CGRect)absoluteFrameForLayer:(CALayer<IJSVGDrawableLayer>*)layer;
|
||||
+ (CGRect)calculateFrameForSublayers:(NSArray<CALayer<IJSVGDrawableLayer>*>*)layers;
|
||||
+ (CGAffineTransform)userSpaceTransformForLayer:(CALayer<IJSVGDrawableLayer>*)layer;
|
||||
+ (void)transformLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
intoUserSpaceUnitsFrom:(CALayer<IJSVGDrawableLayer>*)fromLayer;
|
||||
|
||||
+ (void)logLayer:(CALayer<IJSVGDrawableLayer>*)layer;
|
||||
|
||||
|
||||
@@ -6,23 +6,59 @@
|
||||
// Copyright © 2017 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVG.h"
|
||||
#import "IJSVGGroupLayer.h"
|
||||
#import "IJSVGLayer.h"
|
||||
#import "IJSVGShapeLayer.h"
|
||||
#import "IJSVGTransformLayer.h"
|
||||
#import "IJSVGRootLayer.h"
|
||||
#import <IJSVG/IJSVG.h>
|
||||
#import <IJSVG/IJSVGGroupLayer.h>
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
#import <IJSVG/IJSVGShapeLayer.h>
|
||||
#import <IJSVG/IJSVGTransformLayer.h>
|
||||
#import <IJSVG/IJSVGRootLayer.h>
|
||||
|
||||
CGRect IJSVGLayerGetBoundingBoxBounds(CALayer<IJSVGDrawableLayer>* drawableLayer)
|
||||
{
|
||||
return (CGRect) {
|
||||
.origin = CGPointZero,
|
||||
.size = drawableLayer.boundingBox.size
|
||||
};
|
||||
}
|
||||
|
||||
NSMapTable<NSNumber*, CALayer<IJSVGDrawableLayer>*>* IJSVGLayerDefaultUsageMapTable(void)
|
||||
{
|
||||
return [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory
|
||||
valueOptions:NSPointerFunctionsWeakMemory
|
||||
capacity:3];
|
||||
}
|
||||
|
||||
|
||||
@implementation IJSVGLayer
|
||||
|
||||
@synthesize backingScaleFactor = _backingScaleFactor;
|
||||
@synthesize requiresBackingScale;
|
||||
@synthesize renderQuality;
|
||||
@synthesize blendingMode;
|
||||
@synthesize absoluteOrigin;
|
||||
@synthesize clipPath = _clipPath;
|
||||
@synthesize clipRule = _clipRule;
|
||||
@synthesize clipLayers = _clipLayers;
|
||||
@synthesize clippingTransform;
|
||||
@synthesize clippingBoundingBox;
|
||||
@synthesize maskingClippingRect;
|
||||
@synthesize clipPathTransform;
|
||||
@synthesize colors;
|
||||
@synthesize boundingBox = _boundingBox;
|
||||
@synthesize layerTraits = _layerTraits;
|
||||
@synthesize maskingBoundingBox;
|
||||
@synthesize filter;
|
||||
@synthesize referencingLayer = _referencingLayer;
|
||||
@synthesize outerBoundingBox = _outerBoundingBox;
|
||||
@synthesize maskLayer = _maskLayer;
|
||||
@synthesize treatImplicitOriginAsTransform;
|
||||
@synthesize fillRule;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_clipLayer release]), _clipLayer = nil;
|
||||
(void)([_maskLayer release]), _maskLayer = nil;
|
||||
(void)([_clipRule release]), _clipRule = nil;
|
||||
(void)([_fillRule release]), _fillRule = nil;
|
||||
(void)([_maskingLayer release]), _maskingLayer = nil;
|
||||
[super dealloc];
|
||||
if(_clipPath != NULL) {
|
||||
CGPathRelease(_clipPath);
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
@@ -34,6 +70,11 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id<CAAction>)actionForKey:(NSString*)event
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (CAShapeLayerFillRule)fillRule
|
||||
{
|
||||
return kCAFillRuleNonZero;
|
||||
@@ -61,6 +102,33 @@
|
||||
return IJSVGLayerFillTypeUnknown;
|
||||
}
|
||||
|
||||
+ (CALayer<IJSVGDrawableLayer>*)firstSublayerOfClass:(Class)aClass
|
||||
fromLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
{
|
||||
for(CALayer<IJSVGDrawableLayer>* sublayer in layer.sublayers) {
|
||||
if(sublayer.class == aClass) {
|
||||
return sublayer;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (void)applyAbsoluteTransformForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
toContext:(CGContextRef)ctx
|
||||
{
|
||||
CALayer<IJSVGDrawableLayer>* parentLayer = layer;
|
||||
while((parentLayer = parentLayer.referencingLayer) != nil) {
|
||||
CGContextConcatCTM(ctx, parentLayer.affineTransform);
|
||||
|
||||
// only go up until we find a root layer, at that point, we know
|
||||
// we can stop looking
|
||||
if([parentLayer isKindOfClass:IJSVGRootLayer.class] == YES) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
CGContextConcatCTM(ctx, layer.affineTransform);
|
||||
}
|
||||
|
||||
+ (CGAffineTransform)absoluteTransformForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
{
|
||||
CGAffineTransform identity = CGAffineTransformIdentity;
|
||||
@@ -73,11 +141,26 @@
|
||||
if([parentLayer isKindOfClass:IJSVGRootLayer.class] == YES) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return CGAffineTransformConcat(identity, layer.affineTransform);
|
||||
}
|
||||
|
||||
+ (void)transformLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
intoUserSpaceUnitsFrom:(CALayer<IJSVGDrawableLayer>*)fromLayer
|
||||
{
|
||||
CGAffineTransform transform = layer.affineTransform;
|
||||
CGAffineTransform userSpaceTransform = [IJSVGLayer userSpaceTransformForLayer:fromLayer];
|
||||
layer.affineTransform = CGAffineTransformConcat(transform, userSpaceTransform);
|
||||
}
|
||||
|
||||
+ (CGAffineTransform)userSpaceTransformForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
{
|
||||
CGRect absolutePosition = layer.outerBoundingBox;
|
||||
return CGAffineTransformTranslate(CGAffineTransformIdentity,
|
||||
-CGRectGetMinX(absolutePosition),
|
||||
-CGRectGetMinY(absolutePosition));
|
||||
}
|
||||
|
||||
+ (CALayer<IJSVGDrawableLayer>*)rootLayerForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
{
|
||||
CALayer<IJSVGDrawableLayer>* parentLayer = (CALayer<IJSVGDrawableLayer>*)layer.referencingLayer;
|
||||
@@ -88,106 +171,206 @@
|
||||
return parentLayer;
|
||||
}
|
||||
|
||||
+ (void)renderLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx
|
||||
+ (void)clipContext:(CGContextRef)ctx
|
||||
path:(CGPathRef)path
|
||||
rule:(CAShapeLayerFillRule)rule
|
||||
drawingBlock:(dispatch_block_t)block
|
||||
{
|
||||
CGContextSaveGState(ctx);
|
||||
CGContextAddPath(ctx, path);
|
||||
if([rule isEqualToString:kCAFillRuleEvenOdd] == YES) {
|
||||
CGContextEOClip(ctx);
|
||||
} else {
|
||||
CGContextClip(ctx);
|
||||
}
|
||||
block();
|
||||
CGContextRestoreGState(ctx);
|
||||
}
|
||||
|
||||
+ (void)performBasicRenderOfLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx
|
||||
options:(IJSVGLayerDrawingOptions)options
|
||||
{
|
||||
dispatch_block_t drawingBlock = ^{
|
||||
if(layer.clipPath != NULL) {
|
||||
[self clipContext:ctx
|
||||
path:layer.clipPath
|
||||
rule:layer.clipRule
|
||||
drawingBlock:^{
|
||||
[layer performRenderInContext:ctx];
|
||||
}];
|
||||
return;
|
||||
}
|
||||
[layer performRenderInContext:ctx];
|
||||
};
|
||||
[self applyBlendingMode:layer.blendingMode
|
||||
toContext:ctx
|
||||
drawingBlock:^{
|
||||
// we need to clip first
|
||||
if(layer.clipLayer == nil) {
|
||||
IJSVGLayerDrawingOptions opt = IJSVGLayerDrawingOptionIgnoreClipping;
|
||||
BOOL ignoreClipping = (options & opt) == opt;
|
||||
if(ignoreClipping == YES || layer.clipLayers == nil) {
|
||||
drawingBlock();
|
||||
return;
|
||||
}
|
||||
[self clipContextWithClip:layer.clipLayer
|
||||
toLayer:layer
|
||||
inContext:ctx
|
||||
drawingBlock:drawingBlock];
|
||||
[self clipContextWithClipLayers:layer.clipLayers
|
||||
toLayer:layer
|
||||
inContext:ctx
|
||||
drawingBlock:drawingBlock];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)renderLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx
|
||||
options:(IJSVGLayerDrawingOptions)options
|
||||
{
|
||||
[self performBasicRenderOfLayer:layer
|
||||
inContext:ctx
|
||||
options:options];
|
||||
}
|
||||
|
||||
+ (void)applyBlendingMode:(CGBlendMode)blendMode
|
||||
toContext:(CGContextRef)ctx
|
||||
drawingBlock:(dispatch_block_t)drawingBlock
|
||||
{
|
||||
if (blendMode != kCGBlendModeNormal) {
|
||||
CGContextSaveGState(ctx);
|
||||
CGContextSetBlendMode(ctx, blendMode);
|
||||
if(blendMode == kCGBlendModeNormal) {
|
||||
drawingBlock();
|
||||
CGContextRestoreGState(ctx);
|
||||
return;
|
||||
}
|
||||
CGContextSaveGState(ctx);
|
||||
CGContextSetBlendMode(ctx, blendMode);
|
||||
drawingBlock();
|
||||
CGContextRestoreGState(ctx);
|
||||
}
|
||||
|
||||
/// Shape layers are the only thing we can clip, as they contain a path, however
|
||||
/// the layer passed to us from a clip could have groups contained with in it that
|
||||
/// have transforms on them, so simply recursively iterate over them and concat
|
||||
/// their transforms down to the path and clip at the end with the path.
|
||||
+ (void)recursivelyClip:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
transform:(CGAffineTransform)transform
|
||||
inContext:(CGContextRef)ctx
|
||||
///// Shape layers are the only thing we can clip, as they contain a path, however
|
||||
///// the layer passed to us from a clip could have groups contained with in it that
|
||||
///// have transforms on them, so simply recursively iterate over them and concat
|
||||
///// their transforms down to the path and clip at the end with the path.
|
||||
//+ (void)recursivelyClip:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
// transform:(CGAffineTransform)transform
|
||||
// inContext:(CGContextRef)ctx
|
||||
//{
|
||||
// if([layer isKindOfClass:IJSVGShapeLayer.class]) {
|
||||
// [self clipContextWithShapeLayer:(IJSVGShapeLayer*)layer
|
||||
// transform:transform
|
||||
// inContext:ctx];
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// for(CALayer<IJSVGDrawableLayer>* drawableLayer in layer.sublayers) {
|
||||
// CGAffineTransform drawTransform = CGAffineTransformConcat(transform,
|
||||
// drawableLayer.affineTransform);
|
||||
//
|
||||
// // If its not a shape layer, just go down the tree until we find one
|
||||
// if([drawableLayer isKindOfClass:IJSVGShapeLayer.class] == NO) {
|
||||
// [self recursivelyClip:drawableLayer
|
||||
// transform:drawTransform
|
||||
// inContext:ctx];
|
||||
// continue;
|
||||
// }
|
||||
// IJSVGShapeLayer* shapeLayer = (IJSVGShapeLayer*)drawableLayer;
|
||||
// [self clipContextWithShapeLayer:shapeLayer
|
||||
// transform:transform
|
||||
// inContext:ctx];
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//+ (void)clipContextWithShapeLayer:(IJSVGShapeLayer*)shapeLayer
|
||||
// transform:(CGAffineTransform)transform
|
||||
// inContext:(CGContextRef)ctx
|
||||
//{
|
||||
// CGAffineTransform drawTransform = CGAffineTransformConcat(transform,
|
||||
// shapeLayer.affineTransform);
|
||||
// // Shape layers paths are reset back to 0,0 origin, so in order to be
|
||||
// // correct path, we need to shift it back to where it belongs.
|
||||
// drawTransform = CGAffineTransformTranslate(transform,
|
||||
// shapeLayer.frame.origin.x,
|
||||
// shapeLayer.frame.origin.y);
|
||||
// CGPathRef path = CGPathCreateCopyByTransformingPath(shapeLayer.path,
|
||||
// &drawTransform);
|
||||
// CGContextAddPath(ctx, path);
|
||||
// CGPathRelease(path);
|
||||
//}
|
||||
//
|
||||
//+ (void)clipContextWithClip:(CALayer<IJSVGDrawableLayer>*)clipLayer
|
||||
// toLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
// inContext:(CGContextRef)ctx
|
||||
// drawingBlock:(dispatch_block_t)drawingBlock
|
||||
//{
|
||||
// CGContextSaveGState(ctx);
|
||||
// [self recursivelyClip:clipLayer
|
||||
// transform:clipLayer.affineTransform
|
||||
// inContext:ctx];
|
||||
// if([layer.clipRule isEqualToString:kCAFillRuleEvenOdd]) {
|
||||
// CGContextEOClip(ctx);
|
||||
// } else {
|
||||
// CGContextClip(ctx);
|
||||
// }
|
||||
// drawingBlock();
|
||||
// CGContextRestoreGState(ctx);
|
||||
//}
|
||||
|
||||
+ (void)clipContextWithClipLayers:(NSArray<CALayer<IJSVGDrawableLayer>*>*)clipLayers
|
||||
toLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx
|
||||
drawingBlock:(dispatch_block_t)drawingBlock
|
||||
{
|
||||
if([layer isKindOfClass:IJSVGShapeLayer.class]) {
|
||||
[self clipContextWithShapeLayer:(IJSVGShapeLayer*)layer
|
||||
transform:transform
|
||||
inContext:ctx];
|
||||
CGContextSaveGState(ctx);
|
||||
const CGFloat maskTolerance = .5f;
|
||||
const CGFloat scale = layer.backingScaleFactor;
|
||||
CGRect rect = layer.clippingBoundingBox;
|
||||
|
||||
// weed out the no empty clipPaths
|
||||
if(CGRectEqualToRect(rect, CGRectZero) == YES) {
|
||||
drawingBlock();
|
||||
return;
|
||||
}
|
||||
|
||||
for(CALayer<IJSVGDrawableLayer>* drawableLayer in layer.sublayers) {
|
||||
CGAffineTransform drawTransform = CGAffineTransformConcat(transform,
|
||||
drawableLayer.affineTransform);
|
||||
|
||||
// If its not a shape layer, just go down the tree until we find one
|
||||
if([drawableLayer isKindOfClass:IJSVGShapeLayer.class] == NO) {
|
||||
[self recursivelyClip:drawableLayer
|
||||
transform:drawTransform
|
||||
inContext:ctx];
|
||||
continue;
|
||||
CGSize size = CGSizeMake(CGRectGetWidth(rect),
|
||||
CGRectGetHeight(rect));
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
void (^drawBlock)(CGContextRef maskCtx) = ^(CGContextRef maskCtx) {
|
||||
CGImageRef maskImage = NULL;
|
||||
for(CALayer<IJSVGDrawableLayer>* clipLayer in clipLayers) {
|
||||
CGContextSaveGState(maskCtx);
|
||||
CGRect layerRect = clipLayer.outerBoundingBox;
|
||||
layerRect = CGRectApplyAffineTransform(layerRect, layer.clippingTransform);
|
||||
CGImageRef layerMask = [self newMaskImageForLayer:clipLayer
|
||||
options:IJSVGLayerDrawingOptionIgnoreClipping
|
||||
scale:scale];
|
||||
if(maskImage != NULL) {
|
||||
CGRect maskRect = CGRectInset(rect, -maskTolerance, -maskTolerance);
|
||||
CGContextClipToMask(maskCtx, maskRect, maskImage);
|
||||
}
|
||||
CGContextDrawImage(maskCtx, layerRect, layerMask);
|
||||
CGImageRelease(layerMask);
|
||||
if(maskImage != NULL) {
|
||||
CGImageRelease(maskImage);
|
||||
}
|
||||
maskImage = CGBitmapContextCreateImage(maskCtx);
|
||||
CGContextRestoreGState(maskCtx);
|
||||
}
|
||||
IJSVGShapeLayer* shapeLayer = (IJSVGShapeLayer*)drawableLayer;
|
||||
[self clipContextWithShapeLayer:shapeLayer
|
||||
transform:transform
|
||||
inContext:ctx];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)clipContextWithShapeLayer:(IJSVGShapeLayer*)shapeLayer
|
||||
transform:(CGAffineTransform)transform
|
||||
inContext:(CGContextRef)ctx
|
||||
{
|
||||
CGAffineTransform drawTransform = CGAffineTransformConcat(transform,
|
||||
shapeLayer.affineTransform);
|
||||
// Shape layers paths are reset back to 0,0 origin, so in order to be
|
||||
// correct path, we need to shift it back to where it belongs.
|
||||
drawTransform = CGAffineTransformTranslate(transform,
|
||||
shapeLayer.frame.origin.x,
|
||||
shapeLayer.frame.origin.y);
|
||||
CGPathRef path = CGPathCreateCopyByTransformingPath(shapeLayer.path,
|
||||
&drawTransform);
|
||||
CGContextAddPath(ctx, path);
|
||||
CGPathRelease(path);
|
||||
}
|
||||
|
||||
+ (void)clipContextWithClip:(CALayer<IJSVGDrawableLayer>*)clipLayer
|
||||
toLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
inContext:(CGContextRef)ctx
|
||||
drawingBlock:(dispatch_block_t)drawingBlock
|
||||
{
|
||||
CGContextSaveGState(ctx);
|
||||
[self recursivelyClip:clipLayer
|
||||
transform:CGAffineTransformIdentity
|
||||
inContext:ctx];
|
||||
if([layer.clipRule isEqualToString:kCAFillRuleEvenOdd]) {
|
||||
CGContextEOClip(ctx);
|
||||
} else {
|
||||
CGContextClip(ctx);
|
||||
}
|
||||
CGImageRelease(maskImage);
|
||||
};
|
||||
|
||||
CGImageRef image = [self newImageWithSize:size
|
||||
drawBlock:drawBlock
|
||||
colorSpace:colorSpace
|
||||
bitmapInfo:kCGImageAlphaNone
|
||||
scale:scale];
|
||||
|
||||
// we need to transform the mask rect back based on the inner bounding
|
||||
// box of the layer, as this could be a group layer that inner box is
|
||||
// not at 0,0.
|
||||
CGRect layerRect = layer.innerBoundingBox;
|
||||
CGAffineTransform transform = CGAffineTransformMakeTranslation(CGRectGetMinX(layerRect),
|
||||
CGRectGetMinY(layerRect));
|
||||
rect = CGRectApplyAffineTransform(rect, transform);
|
||||
CGContextClipToMask(ctx, rect, image);
|
||||
drawingBlock();
|
||||
CGImageRelease(image);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
CGContextRestoreGState(ctx);
|
||||
}
|
||||
|
||||
@@ -197,43 +380,76 @@
|
||||
drawingBlock:(dispatch_block_t)drawingBlock
|
||||
{
|
||||
CGContextSaveGState(ctx);
|
||||
CGRect bounds = layer.outerBoundingBox;
|
||||
CGFloat scale = layer.backingScaleFactor;
|
||||
CGImageRef maskImage = [self newMaskImageForLayer:maskLayer
|
||||
options:IJSVGLayerDrawingOptionNone
|
||||
scale:scale];
|
||||
CGContextClipToMask(ctx, bounds, maskImage);
|
||||
CGContextClipToRect(ctx, maskLayer.maskingClippingRect);
|
||||
CGContextClipToMask(ctx, maskLayer.maskingBoundingBox, maskImage);
|
||||
drawingBlock();
|
||||
CGImageRelease(maskImage);
|
||||
CGContextRestoreGState(ctx);
|
||||
}
|
||||
|
||||
+ (CGImageRef)newMaskImageForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
options:(IJSVGLayerDrawingOptions)options
|
||||
scale:(CGFloat)scale
|
||||
{
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
CGImageRef ref = [self newImageForLayer:layer
|
||||
colorSpace:colorSpace
|
||||
bitmapInfo:kCGImageAlphaNone
|
||||
scale:scale];
|
||||
CGImageRef alphaMask = [self newImageForLayer:layer
|
||||
options:options
|
||||
colorSpace:colorSpace
|
||||
bitmapInfo:kCGImageAlphaNone
|
||||
scale:scale];
|
||||
// low - high pairs
|
||||
const CGFloat colors[6] = {
|
||||
0.f, 11.f,
|
||||
0.f, 11.f,
|
||||
0.f, 11.f
|
||||
};
|
||||
CGImageRef masked = CGImageCreateWithMaskingColors(alphaMask, colors);
|
||||
CGImageRelease(alphaMask);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
return ref;
|
||||
return masked;
|
||||
}
|
||||
|
||||
+ (CGImageRef)newImageForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
+ (CGImageRef)newImageWithSize:(CGSize)size
|
||||
drawBlock:(void (^)(CGContextRef context))drawBlock
|
||||
colorSpace:(CGColorSpaceRef)colorSpace
|
||||
bitmapInfo:(uint32_t)bitmapInfo
|
||||
scale:(CGFloat)scale
|
||||
{
|
||||
CGRect frame = layer.outerBoundingBox;
|
||||
CGContextRef offscreenContext = CGBitmapContextCreate(NULL,
|
||||
ceilf(frame.size.width * scale),
|
||||
ceilf(frame.size.height * scale),
|
||||
ceilf(size.width*scale),
|
||||
ceilf(size.height*scale),
|
||||
8, 0, colorSpace, bitmapInfo);
|
||||
|
||||
CGContextSaveGState(offscreenContext);
|
||||
CGContextScaleCTM(offscreenContext, scale, scale);
|
||||
CGContextTranslateCTM(offscreenContext, -frame.origin.x, -frame.origin.y);
|
||||
[layer renderInContext:offscreenContext];
|
||||
drawBlock(offscreenContext);
|
||||
CGImageRef image = CGBitmapContextCreateImage(offscreenContext);
|
||||
CGContextRelease(offscreenContext);
|
||||
return image;
|
||||
}
|
||||
|
||||
+ (CGImageRef)newImageForLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
options:(IJSVGLayerDrawingOptions)options
|
||||
colorSpace:(CGColorSpaceRef)colorSpace
|
||||
bitmapInfo:(uint32_t)bitmapInfo
|
||||
scale:(CGFloat)scale
|
||||
{
|
||||
CALayer<IJSVGDrawableLayer>* referenceLayer = layer.referencingLayer ?: layer;
|
||||
CGRect frame = layer.outerBoundingBox;
|
||||
CGRect bounds = CGRectApplyAffineTransform(layer.innerBoundingBox,
|
||||
[self userSpaceTransformForLayer:referenceLayer]);
|
||||
CGContextRef offscreenContext = CGBitmapContextCreate(NULL,
|
||||
ceilf(frame.size.width*scale),
|
||||
ceilf(frame.size.height*scale),
|
||||
8, 0, colorSpace, bitmapInfo);
|
||||
CGContextScaleCTM(offscreenContext, scale, scale);
|
||||
CGContextConcatCTM(offscreenContext, CGAffineTransformMakeTranslation(-bounds.origin.x,
|
||||
-bounds.origin.y));
|
||||
[IJSVGLayer renderLayer:layer
|
||||
inContext:offscreenContext
|
||||
options:options];
|
||||
CGImageRef image = CGBitmapContextCreateImage(offscreenContext);
|
||||
CGContextRelease(offscreenContext);
|
||||
return image;
|
||||
@@ -261,9 +477,9 @@
|
||||
|
||||
+ (NSArray*)deepestSublayersOfLayer:(CALayer*)layer
|
||||
{
|
||||
NSMutableArray* arr = [[[NSMutableArray alloc] init] autorelease];
|
||||
NSMutableArray* arr = [[NSMutableArray alloc] init];
|
||||
for (CALayer* subLayer in layer.sublayers) {
|
||||
if (subLayer.sublayers.count != 0) {
|
||||
if(subLayer.sublayers.count != 0) {
|
||||
NSArray* moreLayers = [self deepestSublayersOfLayer:(IJSVGLayer*)subLayer];
|
||||
[arr addObjectsFromArray:moreLayers];
|
||||
} else {
|
||||
@@ -273,8 +489,8 @@
|
||||
return arr;
|
||||
}
|
||||
|
||||
+ (void)recursivelyWalkLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
withBlock:(void (^)(CALayer<IJSVGDrawableLayer>* layer, BOOL* stop))block
|
||||
+ (void)recursivelyWalkLayer:(CALayer<IJSVGBasicLayer>*)layer
|
||||
withBlock:(void (^)(CALayer<IJSVGBasicLayer>* layer, BOOL* stop))block
|
||||
{
|
||||
// call for layer and mask if there is one
|
||||
BOOL stop = NO;
|
||||
@@ -284,12 +500,25 @@
|
||||
}
|
||||
|
||||
// sublayers!!
|
||||
for (CALayer<IJSVGDrawableLayer>* aLayer in layer.sublayers) {
|
||||
for (CALayer<IJSVGBasicLayer>* aLayer in layer.sublayers) {
|
||||
[self recursivelyWalkLayer:aLayer
|
||||
withBlock:block];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)setBackingScaleFactor:(CGFloat)scale
|
||||
renderQuality:(IJSVGRenderQuality)quality
|
||||
recursivelyToLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
{
|
||||
[self recursivelyWalkLayer:layer
|
||||
withBlock:^(CALayer<IJSVGDrawableLayer>*sublayer, BOOL *stop) {
|
||||
if(sublayer.requiresBackingScale == YES) {
|
||||
sublayer.backingScaleFactor = scale;
|
||||
}
|
||||
sublayer.renderQuality = quality;
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)logLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
{
|
||||
[self logLayer:layer
|
||||
@@ -333,7 +562,7 @@
|
||||
|
||||
- (void)setBackingScaleFactor:(CGFloat)newFactor
|
||||
{
|
||||
if (_backingScaleFactor == newFactor) {
|
||||
if(_backingScaleFactor == newFactor) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -343,9 +572,9 @@
|
||||
|
||||
// make sure its applied to any mask or clipPath
|
||||
_maskLayer.backingScaleFactor = newFactor;
|
||||
_clipLayer.backingScaleFactor = newFactor;
|
||||
|
||||
[self setNeedsDisplay];
|
||||
for(CALayer<IJSVGDrawableLayer>* clipLayer in _clipLayers) {
|
||||
clipLayer.backingScaleFactor = newFactor;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)performRenderInContext:(CGContextRef)ctx
|
||||
@@ -362,24 +591,6 @@
|
||||
[super renderInContext:ctx];
|
||||
}
|
||||
|
||||
- (void)setConvertMasksToPaths:(BOOL)flag
|
||||
{
|
||||
if (_convertMasksToPaths == flag) {
|
||||
return;
|
||||
}
|
||||
_convertMasksToPaths = flag;
|
||||
if (flag == YES) {
|
||||
if (_maskingLayer != nil) {
|
||||
(void)([_maskingLayer release]), _maskingLayer = nil;
|
||||
}
|
||||
_maskingLayer = [(IJSVGLayer*)self.mask retain];
|
||||
self.mask = nil;
|
||||
} else {
|
||||
self.mask = _maskingLayer;
|
||||
(void)([_maskingLayer release]), _maskingLayer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applySublayerMaskToContext:(CGContextRef)context
|
||||
forSublayer:(IJSVGLayer*)sublayer
|
||||
withOffset:(CGPoint)offset
|
||||
@@ -391,7 +602,7 @@
|
||||
|
||||
// walk up the superlayer chain
|
||||
CALayer* superlayer = self.superlayer;
|
||||
if (IJSVGIsSVGLayer(superlayer) == YES) {
|
||||
if(IJSVGIsSVGLayer(superlayer) == YES) {
|
||||
[(IJSVGLayer*)superlayer applySublayerMaskToContext:context
|
||||
forSublayer:(IJSVGLayer*)self
|
||||
withOffset:layerOffset];
|
||||
@@ -402,14 +613,14 @@
|
||||
|
||||
// if its a group we need to get the lowest level children
|
||||
// and walk up the chain again
|
||||
if ([maskingLayer isKindOfClass:[IJSVGGroupLayer class]]) {
|
||||
if([maskingLayer isKindOfClass:[IJSVGGroupLayer class]]) {
|
||||
NSArray* subs = [IJSVGLayer deepestSublayersOfLayer:maskingLayer];
|
||||
for (IJSVGLayer* subLayer in subs) {
|
||||
[subLayer applySublayerMaskToContext:context
|
||||
forSublayer:(IJSVGLayer*)self
|
||||
withOffset:layerOffset];
|
||||
}
|
||||
} else if ([maskingLayer isKindOfClass:[IJSVGShapeLayer class]]) {
|
||||
} else if([maskingLayer isKindOfClass:[IJSVGShapeLayer class]]) {
|
||||
// is a shape, go for it!
|
||||
CGPathRef maskPath = maskingLayer.path;
|
||||
CGContextTranslateCTM(context, -layerOffset.x, -layerOffset.y);
|
||||
@@ -420,19 +631,14 @@
|
||||
CGContextConcatCTM(context, sublayerTransform);
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)rootLayer
|
||||
{
|
||||
return [self.class rootLayerForLayer:self];
|
||||
}
|
||||
|
||||
- (CGAffineTransform)absoluteTransform
|
||||
{
|
||||
return [IJSVGLayer absoluteTransformForLayer:self];
|
||||
}
|
||||
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
- (BOOL)requiresBackingScale
|
||||
{
|
||||
return _maskLayer != nil || _clipLayer != nil;
|
||||
return _maskLayer != nil || (_clipLayers != nil && _clipLayers.count != 0);
|
||||
}
|
||||
|
||||
- (IJSVGShapeLayer*)maskingLayer
|
||||
@@ -443,12 +649,8 @@
|
||||
- (void)renderInContext:(CGContextRef)ctx
|
||||
{
|
||||
[IJSVGLayer renderLayer:self
|
||||
inContext:ctx];
|
||||
}
|
||||
|
||||
- (id<CAAction>)actionForKey:(NSString*)event
|
||||
{
|
||||
return nil;
|
||||
inContext:ctx
|
||||
options:IJSVGLayerDrawingOptionNone];
|
||||
}
|
||||
|
||||
- (CGRect)absoluteFrame
|
||||
@@ -466,14 +668,6 @@
|
||||
return CGRectIsNull(_outerBoundingBox) == NO ? _outerBoundingBox : self.frame;
|
||||
}
|
||||
|
||||
- (CGRect)outerBoundingBoxBounds
|
||||
{
|
||||
return (CGRect) {
|
||||
.origin = CGPointZero,
|
||||
.size = self.outerBoundingBox.size
|
||||
};
|
||||
}
|
||||
|
||||
- (CGRect)boundingBoxBounds
|
||||
{
|
||||
return (CGRect) {
|
||||
@@ -482,9 +676,12 @@
|
||||
};
|
||||
}
|
||||
|
||||
- (CGRect)strokeBoundingBox
|
||||
- (CGRect)innerBoundingBox
|
||||
{
|
||||
return self.boundingBox;
|
||||
return (CGRect) {
|
||||
.origin = CGPointZero,
|
||||
.size = self.outerBoundingBox.size
|
||||
};
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)referencingLayer
|
||||
@@ -497,4 +694,87 @@
|
||||
return self.sublayers;
|
||||
}
|
||||
|
||||
- (void)setClipPath:(CGPathRef)clipPath
|
||||
{
|
||||
if(_clipPath != NULL) {
|
||||
CGPathRelease(_clipPath);
|
||||
}
|
||||
_clipPath = CGPathRetain(clipPath);
|
||||
}
|
||||
|
||||
- (NSMapTable<NSNumber*,CALayer<IJSVGDrawableLayer>*>*)layerUsageMapTable
|
||||
{
|
||||
if(_layerUsageMapTable == nil) {
|
||||
_layerUsageMapTable = IJSVGLayerDefaultUsageMapTable();
|
||||
}
|
||||
return _layerUsageMapTable;
|
||||
}
|
||||
|
||||
- (void)setLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
forUsageType:(IJSVGLayerUsageType)type
|
||||
{
|
||||
[self.layerUsageMapTable setObject:layer
|
||||
forKey:@(type)];
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)layerForUsageType:(IJSVGLayerUsageType)type
|
||||
{
|
||||
return [self.layerUsageMapTable objectForKey:@(type)];
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)strokeLayer:(IJSVGLayerUsageType*)usageType
|
||||
{
|
||||
CALayer<IJSVGDrawableLayer>* layer = nil;
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokeGeneric]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokeGeneric;
|
||||
return layer;
|
||||
}
|
||||
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokeGradient]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokeGradient;
|
||||
return layer;
|
||||
}
|
||||
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokePattern]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokePattern;
|
||||
return layer;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)addTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
_layerTraits |= traits;
|
||||
}
|
||||
|
||||
- (void)removeTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
_layerTraits = _layerTraits & ~traits;
|
||||
}
|
||||
|
||||
- (BOOL)matchesTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
return (_layerTraits & traits) == traits;
|
||||
}
|
||||
|
||||
- (BOOL)treatImplicitOriginAsTransform
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (IJSVGTraitedColorStorage*)colors
|
||||
{
|
||||
IJSVGTraitedColorStorage* colorList = [[IJSVGTraitedColorStorage alloc] init];
|
||||
for(CALayer<IJSVGDrawableLayer>* layer in self.sublayers) {
|
||||
[colorList unionColorStorage:layer.colors];
|
||||
}
|
||||
return colorList;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)firstSublayerOfClass:(Class)aClass
|
||||
{
|
||||
return [self.class firstSublayerOfClass:aClass
|
||||
fromLayer:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,13 +6,17 @@
|
||||
// Copyright © 2017 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGLayer.h"
|
||||
#import "IJSVGPattern.h"
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
#import <IJSVG/IJSVGPattern.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
@interface IJSVGPatternLayer : IJSVGLayer
|
||||
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* pattern;
|
||||
@property (nonatomic, retain) IJSVGPattern* patternNode;
|
||||
@property (nonatomic, strong) CALayer<IJSVGDrawableLayer>* pattern;
|
||||
@property (nonatomic, strong) IJSVGPattern* patternNode;
|
||||
|
||||
- (void)computeCellSize:(CGSize*)cellSize
|
||||
viewBox:(CGRect*)viewBox
|
||||
origin:(CGPoint*)origin;
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,22 +20,23 @@
|
||||
|
||||
@implementation IJSVGPatternLayer
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_pattern release]), _pattern = nil;
|
||||
(void)([_patternNode release]), _patternNode = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
- (BOOL)requiresBackingScale
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)setBackingScaleFactor:(CGFloat)backingScaleFactor
|
||||
{
|
||||
[super setBackingScaleFactor:backingScaleFactor];
|
||||
[IJSVGLayer setBackingScaleFactor:backingScaleFactor
|
||||
renderQuality:self.renderQuality
|
||||
recursivelyToLayer:self.pattern];
|
||||
}
|
||||
|
||||
void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
|
||||
{
|
||||
// reassign the layer
|
||||
IJSVGPatternLayer* layer = (IJSVGPatternLayer*)info;
|
||||
IJSVGPatternLayer* layer = (__bridge IJSVGPatternLayer*)info;
|
||||
CGSize size = layer.cellSize;
|
||||
CGContextSaveGState(ctx);
|
||||
CGRect rect = CGRectMake(0.f, 0.f, size.width, size.height);
|
||||
@@ -44,15 +45,13 @@ void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
|
||||
IJSVGViewBoxAlignment alignment = layer.patternNode.viewBoxAlignment;
|
||||
IJSVGViewBoxMeetOrSlice meetOrSlice = layer.patternNode.viewBoxMeetOrSlice;
|
||||
CGRect viewBox = layer.viewBox;
|
||||
|
||||
[IJSVGViewBox drawViewBox:viewBox
|
||||
inRect:rect
|
||||
alignment:alignment
|
||||
meetOrSlice:meetOrSlice
|
||||
inContext:ctx
|
||||
drawingBlock:^(CGSize size) {
|
||||
[layer.pattern renderInContext:ctx];
|
||||
}];
|
||||
IJSVGViewBoxDrawingBlock drawBlock = ^(CGFloat scale[]) {
|
||||
[IJSVGLayer renderLayer:layer.pattern
|
||||
inContext:ctx
|
||||
options:IJSVGLayerDrawingOptionNone];
|
||||
};
|
||||
IJSVGContextDrawViewBox(ctx, viewBox, rect, alignment, meetOrSlice,
|
||||
drawBlock);
|
||||
CGContextSaveGState(ctx);
|
||||
};
|
||||
|
||||
@@ -61,6 +60,49 @@ void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
|
||||
return [super referencingLayer] ?: self.superlayer;
|
||||
}
|
||||
|
||||
- (void)computeCellSize:(CGSize*)cellSize
|
||||
viewBox:(CGRect*)viewBox
|
||||
origin:(CGPoint*)origin
|
||||
{
|
||||
CALayer<IJSVGDrawableLayer>* layer = (CALayer<IJSVGDrawableLayer>*)self.referencingLayer;
|
||||
CGRect rect = IJSVGLayerGetBoundingBoxBounds(layer);
|
||||
|
||||
// get the bounds, we need these as when we render we might need to swap
|
||||
// the coordinates over to objectBoundingBox
|
||||
IJSVGUnitLength* xLength = _patternNode.x;
|
||||
IJSVGUnitLength* yLength = _patternNode.y;
|
||||
IJSVGUnitLength* wLength = _patternNode.width;
|
||||
IJSVGUnitLength* hLength = _patternNode.height;
|
||||
|
||||
// actually do the swap if required
|
||||
if(_patternNode.units == IJSVGUnitObjectBoundingBox) {
|
||||
wLength = wLength.lengthByMatchingPercentage;
|
||||
hLength = hLength.lengthByMatchingPercentage;
|
||||
xLength = xLength.lengthByMatchingPercentage;
|
||||
yLength = yLength.lengthByMatchingPercentage;
|
||||
}
|
||||
|
||||
*origin = CGPointMake([xLength computeValue:rect.size.width],
|
||||
[yLength computeValue:rect.size.height]);
|
||||
|
||||
CGFloat width = [wLength computeValue:rect.size.width];
|
||||
CGFloat height = [hLength computeValue:rect.size.height];
|
||||
*cellSize = CGSizeMake(width, height);
|
||||
|
||||
// who knew that patterns have viewBoxes? Not me, but here is an implementation
|
||||
// of it anyway
|
||||
if(_patternNode.viewBox != nil && _patternNode.viewBox.isZeroRect == NO) {
|
||||
IJSVGUnitRect* nViewBox = _patternNode.viewBox;
|
||||
if(_patternNode.contentUnits == IJSVGUnitObjectBoundingBox) {
|
||||
nViewBox = [nViewBox copyByConvertingToUnitsLengthType:IJSVGUnitLengthTypePercentage];
|
||||
}
|
||||
*viewBox = [nViewBox computeValue:rect.size];
|
||||
} else {
|
||||
// no viewbox is assigned, so just map it 1:1 with its cellSize
|
||||
*viewBox = CGRectMake(0.f, 0.f, cellSize->width, cellSize->height);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)drawInContext:(CGContextRef)ctx
|
||||
{
|
||||
// holder for callback
|
||||
@@ -71,53 +113,31 @@ void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
|
||||
CGContextSetFillColorSpace(ctx, patternSpace);
|
||||
CGColorSpaceRelease(patternSpace);
|
||||
|
||||
CGRect rect = self.referencingLayer.boundingBoxBounds;
|
||||
|
||||
IJSVGUnitLength* wLength = _patternNode.width;
|
||||
IJSVGUnitLength* hLength = _patternNode.height;
|
||||
|
||||
if(self.patternNode.units == IJSVGUnitObjectBoundingBox ||
|
||||
self.patternNode.contentUnits == IJSVGUnitObjectBoundingBox) {
|
||||
wLength = wLength.lengthByMatchingPercentage;
|
||||
hLength = hLength.lengthByMatchingPercentage;
|
||||
}
|
||||
|
||||
CGFloat width = [wLength computeValue:rect.size.width];
|
||||
CGFloat height = [hLength computeValue:rect.size.height];
|
||||
_cellSize = CGSizeMake(width, height);
|
||||
|
||||
CALayer<IJSVGDrawableLayer>* layer = (CALayer<IJSVGDrawableLayer>*)self.referencingLayer;
|
||||
|
||||
|
||||
// transform us back into the correct space
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
if (self.patternNode.units == IJSVGUnitUserSpaceOnUse) {
|
||||
CGRect frame = layer.boundingBox;
|
||||
transform = [IJSVGLayer absoluteTransformForLayer:layer];
|
||||
transform = CGAffineTransformTranslate(transform,
|
||||
-CGRectGetMinX(frame),
|
||||
-CGRectGetMinY(frame));
|
||||
if(_patternNode.units == IJSVGUnitUserSpaceOnUse) {
|
||||
transform = [IJSVGLayer userSpaceTransformForLayer:layer];
|
||||
}
|
||||
|
||||
transform = CGAffineTransformConcat(transform, IJSVGConcatTransforms(self.patternNode.transforms));
|
||||
// transform the X and Y shift
|
||||
transform = CGAffineTransformTranslate(transform,
|
||||
[_patternNode.x computeValue:rect.size.width],
|
||||
[_patternNode.y computeValue:rect.size.height]);
|
||||
|
||||
// who knew that patterns have viewBoxes? Not me, but here is an implementation
|
||||
// of it anyway
|
||||
if(_patternNode.viewBox != nil && _patternNode.viewBox.isZeroRect == NO) {
|
||||
if(_patternNode.units == IJSVGUnitObjectBoundingBox) {
|
||||
IJSVGUnitRect* viewBox = nil;
|
||||
viewBox = [[_patternNode.viewBox copyByConvertingToUnitsLengthType:IJSVGUnitLengthTypePercentage] autorelease];
|
||||
_viewBox = [viewBox computeValue:rect.size];
|
||||
}
|
||||
}
|
||||
|
||||
CGPoint origin = CGPointZero;
|
||||
[self computeCellSize:&_cellSize
|
||||
viewBox:&_viewBox
|
||||
origin:&origin];
|
||||
|
||||
// transform the X and Y shift
|
||||
transform = CGAffineTransformConcat(transform, IJSVGConcatTransforms(self.patternNode.transforms));
|
||||
transform = CGAffineTransformTranslate(transform, origin.x, origin.y);
|
||||
|
||||
// its possible that this layer is shifted inwards due to a stroke on the
|
||||
// parent layer
|
||||
transform = CGAffineTransformConcat(transform, [IJSVGLayer userSpaceTransformForLayer:self]);
|
||||
|
||||
// create the pattern
|
||||
CGRect selfBounds = self.boundingBoxBounds;
|
||||
CGRect selfBounds = IJSVGLayerGetBoundingBoxBounds(self);
|
||||
CGPatternRef ref = CGPatternCreate((void*)self, selfBounds,
|
||||
transform, width, height,
|
||||
transform, _cellSize.width, _cellSize.height,
|
||||
kCGPatternTilingConstantSpacing,
|
||||
true, &callbacks);
|
||||
|
||||
@@ -135,4 +155,9 @@ void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
|
||||
return @[self.pattern];
|
||||
}
|
||||
|
||||
- (IJSVGTraitedColorStorage*)colors
|
||||
{
|
||||
return _pattern.colors;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
- (void)renderInContext:(CGContextRef)ctx
|
||||
viewPort:(CGRect)viewPort
|
||||
backingScale:(CGFloat)backingScale
|
||||
quality:(IJSVGRenderQuality)quality;
|
||||
quality:(IJSVGRenderQuality)quality
|
||||
ignoreIntrinsicSize:(BOOL)ignoreIntrinsicSize;
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGRootLayer.h"
|
||||
#import <IJSVG/IJSVGRootLayer.h>
|
||||
|
||||
@implementation IJSVGRootLayer
|
||||
|
||||
@@ -14,19 +14,23 @@
|
||||
{
|
||||
if(self.viewBox != nil) {
|
||||
CGRect viewBox = [self.viewBox computeValue:CGSizeZero];
|
||||
__block IJSVGRootLayer* weakSelf = self;
|
||||
IJSVGViewBoxDrawingBlock drawingBlock = ^(CGSize size) {
|
||||
__weak IJSVGRootLayer* weakSelf = self;
|
||||
IJSVGViewBoxDrawingBlock drawingBlock = ^(CGFloat scale[]) {
|
||||
CGContextSaveGState(ctx);
|
||||
// we have to make sure we set the backing scale factor once
|
||||
// we know how scale this will be drawn at
|
||||
weakSelf.backingScaleFactor *= MAX(size.width, size.height);
|
||||
CGFloat nScale = MIN(scale[0], scale[1]);
|
||||
nScale += weakSelf.backingScaleFactor;
|
||||
weakSelf.backingScaleFactor = nScale;
|
||||
|
||||
// perform the actual render now we have computed backing scale
|
||||
[super performRenderInContext:ctx];
|
||||
CGContextRestoreGState(ctx);
|
||||
};
|
||||
[IJSVGViewBox drawViewBox:viewBox
|
||||
inRect:self.boundingBoxBounds
|
||||
alignment:self.viewBoxAlignment
|
||||
meetOrSlice:self.viewBoxMeetOrSlice
|
||||
inContext:ctx
|
||||
drawingBlock:drawingBlock];
|
||||
|
||||
IJSVGContextDrawViewBox(ctx, viewBox, IJSVGLayerGetBoundingBoxBounds(self),
|
||||
self.viewBoxAlignment,
|
||||
self.viewBoxMeetOrSlice, drawingBlock);
|
||||
return;
|
||||
}
|
||||
[super performRenderInContext:ctx];
|
||||
@@ -34,6 +38,8 @@
|
||||
|
||||
- (void)setBackingScaleFactor:(CGFloat)backingScaleFactor
|
||||
{
|
||||
// get nearest .5f
|
||||
backingScaleFactor = MAX(round(backingScaleFactor * 2.f) / 2.f, .5f);
|
||||
[super setBackingScaleFactor:backingScaleFactor];
|
||||
if(_disableBackingScalePropagation == YES) {
|
||||
return;
|
||||
@@ -43,13 +49,10 @@
|
||||
|
||||
- (void)propagateBackingScalePropertiesToSublayers
|
||||
{
|
||||
__block IJSVGRootLayer* weakSelf = self;
|
||||
for(CALayer<IJSVGDrawableLayer>* layer in self.sublayers) {
|
||||
[IJSVGLayer recursivelyWalkLayer:layer
|
||||
withBlock:^(CALayer<IJSVGDrawableLayer>* propLayer, BOOL *stop) {
|
||||
propLayer.renderQuality = weakSelf.renderQuality;
|
||||
propLayer.backingScaleFactor = weakSelf.backingScaleFactor;
|
||||
}];
|
||||
[IJSVGLayer setBackingScaleFactor:self.backingScaleFactor
|
||||
renderQuality:self.renderQuality
|
||||
recursivelyToLayer:layer];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,15 +60,34 @@
|
||||
viewPort:(CGRect)viewPort
|
||||
backingScale:(CGFloat)backingScale
|
||||
quality:(IJSVGRenderQuality)quality
|
||||
ignoreIntrinsicSize:(BOOL)ignoreIntrinsicSize
|
||||
{
|
||||
CGRect frame = viewPort;
|
||||
IJSVGUnitSize* size = nil;
|
||||
|
||||
// The SVG might have an intrinsic size against it, if so, we need to use
|
||||
// that instead of the viewPort size to make sure we obey the render correctly.
|
||||
if(ignoreIntrinsicSize == NO && (size = self.intrinsicSize) != nil) {
|
||||
CGFloat width = 0.f;
|
||||
CGFloat height = 0.f;
|
||||
if((width = [size.width computeValue:frame.size.width]) != 0.f) {
|
||||
frame.size.width = width;
|
||||
}
|
||||
if((height = [size.height computeValue:frame.size.height]) != 0.f) {
|
||||
frame.size.height = height;
|
||||
}
|
||||
}
|
||||
self.frame = frame;
|
||||
_disableBackingScalePropagation = YES;
|
||||
self.backingScaleFactor = backingScale;
|
||||
self.renderQuality = quality;
|
||||
_disableBackingScalePropagation = NO;
|
||||
[self propagateBackingScalePropertiesToSublayers];
|
||||
[self renderInContext:ctx];
|
||||
}
|
||||
|
||||
- (BOOL)treatImplicitOriginAsTransform
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -14,32 +14,10 @@
|
||||
|
||||
@private
|
||||
IJSVGLayer* _maskingLayer;
|
||||
NSMapTable<NSNumber*, CALayer<IJSVGDrawableLayer>*>* _layerUsageMapTable;
|
||||
}
|
||||
|
||||
@property (nonatomic, assign) IJSVGGradientLayer* gradientFillLayer;
|
||||
@property (nonatomic, assign) IJSVGPatternLayer* patternFillLayer;
|
||||
@property (nonatomic, assign) IJSVGStrokeLayer* strokeLayer;
|
||||
@property (nonatomic, assign) IJSVGGradientLayer* gradientStrokeLayer;
|
||||
@property (nonatomic, assign) IJSVGPatternLayer* patternStrokeLayer;
|
||||
@property (nonatomic, assign) CGFloat backingScaleFactor;
|
||||
@property (nonatomic, readonly) BOOL requiresBackingScaleHelp;
|
||||
@property (nonatomic, assign) IJSVGRenderQuality renderQuality;
|
||||
@property (nonatomic, assign) CGBlendMode blendingMode;
|
||||
@property (nonatomic, assign) CGPoint absoluteOrigin;
|
||||
@property (nonatomic, assign) CGPoint originalPathOrigin;
|
||||
@property (nonatomic, assign) BOOL convertMasksToPaths;
|
||||
@property (nonatomic, assign) IJSVGPrimitivePathType primitiveType;
|
||||
@property (nonatomic, readonly) CGRect computedFrame;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* clipLayer;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* maskLayer;
|
||||
@property (nonatomic, readonly) CALayer<IJSVGDrawableLayer>* rootLayer;
|
||||
@property (nonatomic, readonly) CGRect absoluteFrame;
|
||||
@property (nonatomic, assign) CGRect boundingBox;
|
||||
@property (nonatomic, assign) CGRect outerBoundingBox;
|
||||
@property (nonatomic, readonly) CGRect boundingBoxBounds;
|
||||
@property (nonatomic, assign) CALayer<IJSVGDrawableLayer>* referencingLayer;
|
||||
@property (nonatomic, assign) CGRect strokeBoundingBox;
|
||||
@property (nonatomic, copy) CAShapeLayerFillRule clipRule;
|
||||
|
||||
- (void)applySublayerMaskToContext:(CGContextRef)context
|
||||
forSublayer:(IJSVGLayer*)sublayer
|
||||
|
||||
@@ -6,23 +6,47 @@
|
||||
// Copyright © 2017 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGGroupLayer.h"
|
||||
#import "IJSVGShapeLayer.h"
|
||||
#import <IJSVG/IJSVGGroupLayer.h>
|
||||
#import <IJSVG/IJSVGShapeLayer.h>
|
||||
#import <IJSVG/IJSVGStrokeLayer.h>
|
||||
#import <IJSVG/IJSVGGradientLayer.h>
|
||||
#import <IJSVG/IJSVGTraitedColorStorage.h>
|
||||
#import <IJSVG/IJSVGPatternLayer.h>
|
||||
|
||||
@implementation IJSVGShapeLayer
|
||||
|
||||
@synthesize backingScaleFactor = _backingScaleFactor;
|
||||
@synthesize requiresBackingScale;
|
||||
@synthesize renderQuality;
|
||||
@synthesize blendingMode;
|
||||
@synthesize absoluteOrigin;
|
||||
@synthesize clipPath = _clipPath;
|
||||
@synthesize clipRule;
|
||||
@synthesize clipLayers = _clipLayers;
|
||||
@synthesize clippingTransform;
|
||||
@synthesize clippingBoundingBox;
|
||||
@synthesize maskingClippingRect;
|
||||
@synthesize clipPathTransform;
|
||||
@synthesize colors;
|
||||
@synthesize boundingBox;
|
||||
@synthesize layerTraits = _layerTraits;
|
||||
@synthesize maskingBoundingBox;
|
||||
@synthesize filter;
|
||||
@synthesize referencingLayer = _referencingLayer;
|
||||
@synthesize outerBoundingBox;
|
||||
@synthesize maskLayer = _maskLayer;
|
||||
@synthesize treatImplicitOriginAsTransform;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_clipLayer release]), _clipLayer = nil;
|
||||
(void)([_maskLayer release]), _maskLayer = nil;
|
||||
(void)([_maskingLayer release]), _maskingLayer = nil;
|
||||
(void)([_clipRule release]), _clipRule = nil;
|
||||
[super dealloc];
|
||||
if(_clipPath != NULL) {
|
||||
CGPathRelease(_clipPath);
|
||||
}
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)rootLayer
|
||||
- (id<CAAction>)actionForKey:(NSString*)event
|
||||
{
|
||||
return [IJSVGLayer rootLayerForLayer:self];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (CGRect)absoluteFrame
|
||||
@@ -48,14 +72,27 @@
|
||||
};
|
||||
}
|
||||
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
- (CGRect)innerBoundingBox
|
||||
{
|
||||
return _maskLayer != nil || _clipLayer != nil;
|
||||
return self.bounds;
|
||||
}
|
||||
|
||||
- (BOOL)requiresBackingScale
|
||||
{
|
||||
return _maskLayer != nil || (_clipLayers != nil && _clipLayers.count != 0);
|
||||
}
|
||||
|
||||
- (void)setClipPath:(CGPathRef)clipPath
|
||||
{
|
||||
if(_clipPath != NULL) {
|
||||
CGPathRelease(_clipPath);
|
||||
}
|
||||
_clipPath = CGPathRetain(clipPath);
|
||||
}
|
||||
|
||||
- (void)setBackingScaleFactor:(CGFloat)newFactor
|
||||
{
|
||||
if (_backingScaleFactor == newFactor) {
|
||||
if(_backingScaleFactor == newFactor) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -65,7 +102,10 @@
|
||||
|
||||
// make sure its applied to any mask or clipPath
|
||||
_maskLayer.backingScaleFactor = newFactor;
|
||||
_clipLayer.backingScaleFactor = newFactor;
|
||||
|
||||
for(CALayer<IJSVGDrawableLayer>* clipLayer in _clipLayers) {
|
||||
clipLayer.backingScaleFactor = newFactor;
|
||||
}
|
||||
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
@@ -84,24 +124,6 @@
|
||||
[super renderInContext:ctx];
|
||||
}
|
||||
|
||||
- (void)setConvertMasksToPaths:(BOOL)flag
|
||||
{
|
||||
if (_convertMasksToPaths == flag) {
|
||||
return;
|
||||
}
|
||||
_convertMasksToPaths = flag;
|
||||
if (flag == YES) {
|
||||
if (_maskingLayer != nil) {
|
||||
(void)([_maskingLayer release]), _maskingLayer = nil;
|
||||
}
|
||||
_maskingLayer = [(IJSVGLayer*)self.mask retain];
|
||||
self.mask = nil;
|
||||
} else {
|
||||
self.mask = _maskingLayer;
|
||||
(void)([_maskingLayer release]), _maskingLayer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applySublayerMaskToContext:(CGContextRef)context
|
||||
forSublayer:(IJSVGLayer*)sublayer
|
||||
withOffset:(CGPoint)offset
|
||||
@@ -113,7 +135,7 @@
|
||||
|
||||
// walk up the superlayer chain
|
||||
CALayer* superlayer = self.superlayer;
|
||||
if (IJSVGIsSVGLayer(superlayer) == YES) {
|
||||
if(IJSVGIsSVGLayer(superlayer) == YES) {
|
||||
[(IJSVGLayer*)superlayer applySublayerMaskToContext:context
|
||||
forSublayer:(IJSVGLayer*)self
|
||||
withOffset:layerOffset];
|
||||
@@ -124,14 +146,14 @@
|
||||
|
||||
// if its a group we need to get the lowest level children
|
||||
// and walk up the chain again
|
||||
if ([maskingLayer isKindOfClass:[IJSVGGroupLayer class]]) {
|
||||
if([maskingLayer isKindOfClass:[IJSVGGroupLayer class]]) {
|
||||
NSArray* subs = [IJSVGLayer deepestSublayersOfLayer:maskingLayer];
|
||||
for (IJSVGLayer* subLayer in subs) {
|
||||
[subLayer applySublayerMaskToContext:context
|
||||
forSublayer:(IJSVGLayer*)self
|
||||
withOffset:layerOffset];
|
||||
}
|
||||
} else if ([maskingLayer isKindOfClass:[IJSVGShapeLayer class]]) {
|
||||
} else if([maskingLayer isKindOfClass:[IJSVGShapeLayer class]]) {
|
||||
// is a shape, go for it!
|
||||
CGPathRef maskPath = maskingLayer.path;
|
||||
CGContextTranslateCTM(context, -layerOffset.x, -layerOffset.y);
|
||||
@@ -150,11 +172,47 @@
|
||||
- (void)renderInContext:(CGContextRef)ctx
|
||||
{
|
||||
[IJSVGLayer renderLayer:(IJSVGLayer*)self
|
||||
inContext:ctx];
|
||||
inContext:ctx
|
||||
options:IJSVGLayerDrawingOptionNone];
|
||||
}
|
||||
|
||||
- (id<CAAction>)actionForKey:(NSString*)event
|
||||
- (NSMapTable<NSNumber*,CALayer<IJSVGDrawableLayer>*>*)layerUsageMapTable
|
||||
{
|
||||
if(_layerUsageMapTable == nil) {
|
||||
_layerUsageMapTable = IJSVGLayerDefaultUsageMapTable();
|
||||
}
|
||||
return _layerUsageMapTable;
|
||||
}
|
||||
|
||||
- (void)setLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
forUsageType:(IJSVGLayerUsageType)type
|
||||
{
|
||||
[self.layerUsageMapTable setObject:layer
|
||||
forKey:@(type)];
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)layerForUsageType:(IJSVGLayerUsageType)type
|
||||
{
|
||||
return [self.layerUsageMapTable objectForKey:@(type)];
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)strokeLayer:(IJSVGLayerUsageType*)usageType
|
||||
{
|
||||
CALayer<IJSVGDrawableLayer>* layer = nil;
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokeGeneric]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokeGeneric;
|
||||
return layer;
|
||||
}
|
||||
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokeGradient]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokeGradient;
|
||||
return layer;
|
||||
}
|
||||
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokePattern]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokePattern;
|
||||
return layer;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -163,4 +221,92 @@
|
||||
return self.sublayers;
|
||||
}
|
||||
|
||||
- (BOOL)treatImplicitOriginAsTransform
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)addTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
_layerTraits |= traits;
|
||||
}
|
||||
|
||||
- (void)removeTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
_layerTraits = _layerTraits & ~traits;
|
||||
}
|
||||
|
||||
- (BOOL)matchesTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
return (_layerTraits & traits) == traits;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)firstSublayerOfClass:(Class)aClass
|
||||
{
|
||||
return [IJSVGLayer firstSublayerOfClass:aClass
|
||||
fromLayer:self];
|
||||
}
|
||||
|
||||
- (IJSVGTraitedColorStorage*)colors
|
||||
{
|
||||
IJSVGTraitedColorStorage* list = [[IJSVGTraitedColorStorage alloc] init];
|
||||
|
||||
// we have a fill color
|
||||
if([self matchesTraits:IJSVGLayerTraitFilled] == YES) {
|
||||
IJSVGShapeLayer* fillLayer = nil;
|
||||
if((fillLayer = (IJSVGShapeLayer*)[self layerForUsageType:IJSVGLayerUsageTypeFillGeneric]) != nil) {
|
||||
CGColorRef colorRef = NULL;
|
||||
if((colorRef = fillLayer.fillColor) != NULL) {
|
||||
NSColor* nsColor = [NSColor colorWithCGColor:colorRef];
|
||||
IJSVGTraitedColor* color = [IJSVGTraitedColor colorWithColor:nsColor
|
||||
traits:IJSVGColorUsageTraitFill];
|
||||
[list addColor:color];
|
||||
}
|
||||
}
|
||||
|
||||
// patterns
|
||||
if((fillLayer = (IJSVGShapeLayer*)[self layerForUsageType:IJSVGLayerUsageTypeFillPattern]) != nil) {
|
||||
IJSVGTraitedColorStorage* storage = fillLayer.colors;
|
||||
[storage addTraits:IJSVGColorUsageTraitFill];
|
||||
[list unionColorStorage:storage];
|
||||
}
|
||||
|
||||
// gradients
|
||||
if((fillLayer = (IJSVGShapeLayer*)[self layerForUsageType:IJSVGLayerUsageTypeFillGradient]) != nil) {
|
||||
IJSVGTraitedColorStorage* storage = fillLayer.colors;
|
||||
[storage addTraits:IJSVGColorUsageTraitGradientStop];
|
||||
[list unionColorStorage:storage];
|
||||
}
|
||||
}
|
||||
|
||||
// we have a stroke color
|
||||
if([self matchesTraits:IJSVGLayerTraitStroked] == YES) {
|
||||
IJSVGStrokeLayer* strokeLayer = nil;
|
||||
if((strokeLayer = (IJSVGStrokeLayer*)[self layerForUsageType:IJSVGLayerUsageTypeStrokeGeneric]) != nil) {
|
||||
CGColorRef colorRef = NULL;
|
||||
if((colorRef = strokeLayer.strokeColor) != NULL) {
|
||||
NSColor* nsColor = [NSColor colorWithCGColor:colorRef];
|
||||
IJSVGTraitedColor* color = [IJSVGTraitedColor colorWithColor:nsColor
|
||||
traits:IJSVGColorUsageTraitStroke];
|
||||
[list addColor:color];
|
||||
}
|
||||
}
|
||||
|
||||
// patterns
|
||||
if((strokeLayer = (IJSVGStrokeLayer*)[self layerForUsageType:IJSVGLayerUsageTypeStrokePattern]) != nil) {
|
||||
IJSVGTraitedColorStorage* storage = strokeLayer.colors;
|
||||
[storage addTraits:IJSVGColorUsageTraitFill];
|
||||
[list unionColorStorage:storage];
|
||||
}
|
||||
|
||||
// gradients
|
||||
if((strokeLayer = (IJSVGStrokeLayer*)[self layerForUsageType:IJSVGLayerUsageTypeStrokeGradient]) != nil) {
|
||||
IJSVGTraitedColorStorage* storage = strokeLayer.colors;
|
||||
[storage addTraits:IJSVGColorUsageTraitGradientStop];
|
||||
[list unionColorStorage:storage];
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2017 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGShapeLayer.h"
|
||||
#import <IJSVG/IJSVGShapeLayer.h>
|
||||
|
||||
@interface IJSVGStrokeLayer : IJSVGShapeLayer
|
||||
|
||||
|
||||
@@ -6,15 +6,8 @@
|
||||
// Copyright © 2017 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGStrokeLayer.h"
|
||||
#import <IJSVG/IJSVGStrokeLayer.h>
|
||||
|
||||
@implementation IJSVGStrokeLayer
|
||||
|
||||
- (CGRect)outerBoundingBox
|
||||
{
|
||||
return CGRectMake(-self.lineWidth / 2.f, -self.lineWidth / 2.f,
|
||||
self.boundingBox.size.width + self.lineWidth,
|
||||
self.boundingBox.size.height + self.lineWidth);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// IJSVGTileLayer.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 29/06/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
|
||||
@interface IJSVGTileLayer : CATiledLayer <IJSVGDrawableLayer> {
|
||||
@private
|
||||
NSMapTable<NSNumber*, CALayer<IJSVGDrawableLayer>*>* _layerUsageMapTable;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,150 @@
|
||||
//
|
||||
// IJSVGTileLayer.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 29/06/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGTileLayer.h"
|
||||
|
||||
@implementation IJSVGTileLayer
|
||||
|
||||
@synthesize clipLayers;
|
||||
@synthesize backingScaleFactor;
|
||||
@synthesize renderQuality;
|
||||
@synthesize requiresBackingScale;
|
||||
@synthesize maskLayer = _maskLayer;
|
||||
@synthesize fillRule = _fillRule;
|
||||
@synthesize clipRule = _clipRule;
|
||||
@synthesize absoluteFrame;
|
||||
@synthesize boundingBox;
|
||||
@synthesize outerBoundingBox;
|
||||
@synthesize filter = _filter;
|
||||
@synthesize innerBoundingBox;
|
||||
@synthesize maskingBoundingBox;
|
||||
@synthesize maskingClippingRect;
|
||||
@synthesize clippingBoundingBox;
|
||||
@synthesize clippingTransform;
|
||||
@synthesize layerTraits = _layerTraits;
|
||||
@synthesize clipPath = _clipPath;
|
||||
@synthesize clipPathTransform;
|
||||
@synthesize referencingLayer = _referencingLayer;
|
||||
@synthesize absoluteOrigin;
|
||||
@synthesize blendingMode;
|
||||
@synthesize colors;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if(_clipPath != NULL) {
|
||||
CGPathRelease(_clipPath);
|
||||
}
|
||||
}
|
||||
|
||||
- (id<CAAction>)actionForKey:(NSString*)event
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)referencedLayer
|
||||
{
|
||||
return self.sublayers.firstObject;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)referencingLayer
|
||||
{
|
||||
return _referencingLayer ?: self.superlayer;
|
||||
}
|
||||
|
||||
- (void)renderInContext:(CGContextRef)ctx
|
||||
{
|
||||
[IJSVGLayer renderLayer:self
|
||||
inContext:ctx
|
||||
options:IJSVGLayerDrawingOptionNone];
|
||||
}
|
||||
|
||||
- (void)performRenderInContext:(CGContextRef)ctx
|
||||
{
|
||||
[super renderInContext:ctx];
|
||||
}
|
||||
|
||||
- (NSArray<CALayer<IJSVGDrawableLayer>*>*)debugLayers
|
||||
{
|
||||
return self.sublayers;
|
||||
}
|
||||
|
||||
- (void)setClipPath:(CGPathRef)clipPath
|
||||
{
|
||||
if(_clipPath != NULL) {
|
||||
CGPathRelease(_clipPath);
|
||||
}
|
||||
_clipPath = CGPathRetain(clipPath);
|
||||
}
|
||||
|
||||
- (NSMapTable<NSNumber*,CALayer<IJSVGDrawableLayer>*>*)layerUsageMapTable
|
||||
{
|
||||
if(_layerUsageMapTable == nil) {
|
||||
_layerUsageMapTable = IJSVGLayerDefaultUsageMapTable();
|
||||
}
|
||||
return _layerUsageMapTable;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)layerForUsageType:(IJSVGLayerUsageType)type
|
||||
{
|
||||
return [self.layerUsageMapTable objectForKey:@(type)];
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)strokeLayer:(IJSVGLayerUsageType*)usageType
|
||||
{
|
||||
CALayer<IJSVGDrawableLayer>* layer = nil;
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokeGeneric]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokeGeneric;
|
||||
return layer;
|
||||
}
|
||||
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokeGradient]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokeGradient;
|
||||
return layer;
|
||||
}
|
||||
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokePattern]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokePattern;
|
||||
return layer;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)setLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
forUsageType:(IJSVGLayerUsageType)type
|
||||
{
|
||||
[self.layerUsageMapTable setObject:layer
|
||||
forKey:@(type)];
|
||||
}
|
||||
|
||||
- (void)addTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
_layerTraits |= traits;
|
||||
}
|
||||
|
||||
- (void)removeTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
_layerTraits = _layerTraits & ~traits;
|
||||
}
|
||||
|
||||
- (BOOL)matchesTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
return (_layerTraits & traits) == traits;
|
||||
}
|
||||
|
||||
- (BOOL)treatImplicitOriginAsTransform
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)firstSublayerOfClass:(Class)aClass
|
||||
{
|
||||
return [IJSVGLayer firstSublayerOfClass:aClass
|
||||
fromLayer:self];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -9,13 +9,9 @@
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
|
||||
@interface IJSVGTransformLayer : CATransformLayer <IJSVGDrawableLayer>
|
||||
|
||||
@property (nonatomic, assign) CGBlendMode blendingMode;
|
||||
@property (nonatomic, retain) CALayer<IJSVGDrawableLayer>* clipLayer;
|
||||
@property (nonatomic, readonly) CGPoint absoluteOrigin;
|
||||
@property (nonatomic, readonly) CGRect computedFrame;
|
||||
@property (nonatomic, readonly) CALayer<IJSVGDrawableLayer>* referencedLayer;
|
||||
@property (nonatomic, assign) CALayer<IJSVGDrawableLayer>* referencingLayer;
|
||||
@interface IJSVGTransformLayer : CATransformLayer <IJSVGDrawableLayer> {
|
||||
@private
|
||||
NSMapTable<NSNumber*, CALayer<IJSVGDrawableLayer>*>* _layerUsageMapTable;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,29 +6,45 @@
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGTransformLayer.h"
|
||||
#import <IJSVG/IJSVGTransformLayer.h>
|
||||
#import <IJSVG/IJSVGTraitedColorStorage.h>
|
||||
|
||||
@implementation IJSVGTransformLayer
|
||||
|
||||
@synthesize clipLayers;
|
||||
@synthesize backingScaleFactor;
|
||||
@synthesize renderQuality;
|
||||
@synthesize requiresBackingScaleHelp;
|
||||
@synthesize requiresBackingScale;
|
||||
@synthesize maskLayer = _maskLayer;
|
||||
@synthesize fillRule = _fillRule;
|
||||
@synthesize clipRule = _clipRule;
|
||||
@synthesize absoluteFrame;
|
||||
@synthesize boundingBox;
|
||||
@synthesize boundingBoxBounds;
|
||||
@synthesize strokeBoundingBox;
|
||||
@synthesize outerBoundingBox;
|
||||
@synthesize filter = _filter;
|
||||
@synthesize innerBoundingBox;
|
||||
@synthesize maskingBoundingBox;
|
||||
@synthesize maskingClippingRect;
|
||||
@synthesize clippingBoundingBox;
|
||||
@synthesize clippingTransform;
|
||||
@synthesize layerTraits = _layerTraits;
|
||||
@synthesize clipPath = _clipPath;
|
||||
@synthesize clipPathTransform;
|
||||
@synthesize colors;
|
||||
@synthesize absoluteOrigin;
|
||||
@synthesize blendingMode;
|
||||
@synthesize referencingLayer = _referencingLayer;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)[_maskLayer release], _maskLayer = nil;
|
||||
(void)[_fillRule release], _fillRule = nil;
|
||||
(void)[_clipRule release], _clipRule = nil;
|
||||
(void)[_clipLayer release], _clipLayer = nil;
|
||||
[super dealloc];
|
||||
if(_clipPath != NULL) {
|
||||
CGPathRelease(_clipPath);
|
||||
}
|
||||
}
|
||||
|
||||
- (id<CAAction>)actionForKey:(NSString*)event
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)referencedLayer
|
||||
@@ -36,24 +52,16 @@
|
||||
return self.sublayers.firstObject;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer> *)referencingLayer {
|
||||
- (CALayer<IJSVGDrawableLayer> *)referencingLayer
|
||||
{
|
||||
return _referencingLayer ?: self.superlayer;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)rootLayer
|
||||
{
|
||||
return [IJSVGLayer rootLayerForLayer:self];
|
||||
}
|
||||
|
||||
- (BOOL)requiresBackingScaleHelp
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)renderInContext:(CGContextRef)ctx
|
||||
{
|
||||
[IJSVGLayer renderLayer:self
|
||||
inContext:ctx];
|
||||
inContext:ctx
|
||||
options:IJSVGLayerDrawingOptionNone];
|
||||
}
|
||||
|
||||
- (void)performRenderInContext:(CGContextRef)ctx
|
||||
@@ -66,4 +74,87 @@
|
||||
return self.sublayers;
|
||||
}
|
||||
|
||||
- (void)setClipPath:(CGPathRef)clipPath
|
||||
{
|
||||
if(_clipPath != NULL) {
|
||||
CGPathRelease(_clipPath);
|
||||
}
|
||||
_clipPath = CGPathRetain(clipPath);
|
||||
}
|
||||
|
||||
- (NSMapTable<NSNumber*,CALayer<IJSVGDrawableLayer>*>*)layerUsageMapTable
|
||||
{
|
||||
if(_layerUsageMapTable == nil) {
|
||||
_layerUsageMapTable = IJSVGLayerDefaultUsageMapTable();
|
||||
}
|
||||
return _layerUsageMapTable;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)layerForUsageType:(IJSVGLayerUsageType)type
|
||||
{
|
||||
return [self.layerUsageMapTable objectForKey:@(type)];
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)strokeLayer:(IJSVGLayerUsageType*)usageType
|
||||
{
|
||||
CALayer<IJSVGDrawableLayer>* layer = nil;
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokeGeneric]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokeGeneric;
|
||||
return layer;
|
||||
}
|
||||
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokeGradient]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokeGradient;
|
||||
return layer;
|
||||
}
|
||||
|
||||
if((layer = [self layerForUsageType:IJSVGLayerUsageTypeStrokePattern]) != nil) {
|
||||
*usageType = IJSVGLayerUsageTypeStrokePattern;
|
||||
return layer;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)setLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
forUsageType:(IJSVGLayerUsageType)type
|
||||
{
|
||||
[self.layerUsageMapTable setObject:layer
|
||||
forKey:@(type)];
|
||||
}
|
||||
|
||||
- (void)addTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
_layerTraits |= traits;
|
||||
}
|
||||
|
||||
- (void)removeTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
_layerTraits = _layerTraits & ~traits;
|
||||
}
|
||||
|
||||
- (BOOL)matchesTraits:(IJSVGLayerTraits)traits
|
||||
{
|
||||
return (_layerTraits & traits) == traits;
|
||||
}
|
||||
|
||||
- (BOOL)treatImplicitOriginAsTransform
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (CALayer<IJSVGDrawableLayer>*)firstSublayerOfClass:(Class)aClass
|
||||
{
|
||||
return [IJSVGLayer firstSublayerOfClass:aClass
|
||||
fromLayer:self];
|
||||
}
|
||||
|
||||
- (IJSVGTraitedColorStorage*)colors
|
||||
{
|
||||
IJSVGTraitedColorStorage* colorList = [[IJSVGTraitedColorStorage alloc] init];
|
||||
for(CALayer<IJSVGDrawableLayer>* layer in self.sublayers) {
|
||||
[colorList unionColorStorage:layer.colors];
|
||||
}
|
||||
return colorList;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// IJSVGFilterEffectGaussianBlur.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 18/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGFilterEffect.h>
|
||||
|
||||
@interface IJSVGFilterEffectGaussianBlur : IJSVGFilterEffect
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// IJSVGFilterEffectGaussianBlur.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 18/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGFilterEffectGaussianBlur.h>
|
||||
#import <IJSVG/IJSVGThreadManager.h>
|
||||
|
||||
@implementation IJSVGFilterEffectGaussianBlur
|
||||
|
||||
+ (CIFilter*)sharedFilter
|
||||
{
|
||||
IJSVGThreadManager* manager = IJSVGThreadManager.currentManager;
|
||||
NSString* key = @"CIFilterGaussianBlur";
|
||||
CIFilter* filter = nil;
|
||||
if((filter = [manager userInfoObjectForKey:key]) == nil) {
|
||||
filter = [CIFilter filterWithName:@"CIGaussianBlur"];
|
||||
[manager setUserInfoObject:filter
|
||||
forKey:key];
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
- (CIImage*)processImage:(CIImage*)image
|
||||
{
|
||||
CIFilter* filter = [self.class sharedFilter];
|
||||
[filter setDefaults];
|
||||
[filter setValue:image forKey:kCIInputImageKey];
|
||||
[filter setValue:@(self.stdDeviation.value) forKey:kCIInputRadiusKey];
|
||||
return [filter valueForKey:kCIOutputImageKey];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// IJSVGClipPath.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 29/05/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
|
||||
@interface IJSVGClipPath : IJSVGGroup {
|
||||
}
|
||||
|
||||
@property (nonatomic, readonly) IJSVGWindingRule computedClipRule;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// IJSVGClipPath.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 29/05/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGClipPath.h>
|
||||
#import <IJSVG/IJSVGRootNode.h>
|
||||
|
||||
@implementation IJSVGClipPath
|
||||
|
||||
+ (IJSVGBitFlags*)allowedAttributes
|
||||
{
|
||||
IJSVGBitFlags64* storage = [[IJSVGBitFlags64 alloc] init];
|
||||
[storage addBits:[super allowedAttributes]];
|
||||
[storage setBit:IJSVGNodeAttributeX];
|
||||
[storage setBit:IJSVGNodeAttributeY];
|
||||
[storage setBit:IJSVGNodeAttributeWidth];
|
||||
[storage setBit:IJSVGNodeAttributeHeight];
|
||||
[storage setBit:IJSVGNodeAttributeClipPathUnits];
|
||||
[storage setBit:IJSVGNodeAttributeClipRule];
|
||||
return storage;
|
||||
}
|
||||
|
||||
- (void)setDefaults
|
||||
{
|
||||
self.units = IJSVGUnitObjectBoundingBox;
|
||||
self.contentUnits = IJSVGUnitUserSpaceOnUse;
|
||||
self.windingRule = IJSVGWindingRuleNonZero;
|
||||
self.overflowVisibility = IJSVGOverflowVisibilityHidden;
|
||||
self.fill = [IJSVGColorNode colorNodeWithColor:NSColor.whiteColor];
|
||||
}
|
||||
|
||||
- (IJSVGUnitType)contentUnitsWithReferencingNodeBounds:(CGRect*)bounds
|
||||
{
|
||||
IJSVGNode* node = nil;
|
||||
IJSVGUnitType units = [self contentUnitsWithReferencingNode:&node];
|
||||
if(units == IJSVGUnitUserSpaceOnUse) {
|
||||
*bounds = node.rootNode.bounds;
|
||||
} else {
|
||||
*bounds = node.parentNode.bounds;
|
||||
}
|
||||
return units;
|
||||
}
|
||||
|
||||
- (void)postProcess
|
||||
{
|
||||
// clip paths only allow shapes in them, nothing else, we can simply
|
||||
// check the node types for the trait of pathed
|
||||
IJSVGNodeTraits childTraits = IJSVGNodeTraitPathed;
|
||||
for(IJSVGNode* childNode in self.children.copy) {
|
||||
if([childNode matchesTraits:childTraits] == NO) {
|
||||
BOOL remove = YES;
|
||||
IJSVGNodeType type = childNode.type;
|
||||
if(type == IJSVGNodeTypeUse) {
|
||||
remove = [(IJSVGGroup*)childNode childrenMatchTraits:childTraits] == NO;
|
||||
}
|
||||
if(remove == YES) {
|
||||
[self removeChild:childNode];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (IJSVGWindingRule)computedClipRule
|
||||
{
|
||||
// find the first use of a clipRule that is useful
|
||||
__block IJSVGWindingRule rule = IJSVGWindingRuleInherit;
|
||||
__weak IJSVGClipPath* weakSelf = self;
|
||||
IJSVGNodeWalkHandler handler = ^(IJSVGNode *node, BOOL *allowChildNodes,
|
||||
BOOL *stop) {
|
||||
if(node == weakSelf) {
|
||||
return;
|
||||
}
|
||||
IJSVGWindingRule clipRule = node.clipRule;
|
||||
if(clipRule != IJSVGWindingRuleInherit) {
|
||||
rule = clipRule;
|
||||
*stop = YES;
|
||||
}
|
||||
};
|
||||
[IJSVGNode walkNodeTree:self
|
||||
handler:handler];
|
||||
return rule;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -12,7 +12,8 @@
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) NSColor* color;
|
||||
@property (nonatomic, strong) NSColor* color;
|
||||
@property (nonatomic, assign) BOOL isNoneOrTransparent;
|
||||
|
||||
+ (IJSVGNode*)colorNodeWithColor:(NSColor*)color;
|
||||
|
||||
|
||||
@@ -6,19 +6,13 @@
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGColorNode.h"
|
||||
#import <IJSVG/IJSVGColorNode.h>
|
||||
|
||||
@implementation IJSVGColorNode
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)[_color release], _color = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
+ (IJSVGNode*)colorNodeWithColor:(NSColor *)color
|
||||
{
|
||||
return [[[self alloc] initWithColor:color] autorelease];
|
||||
return [[self alloc] initWithColor:color];
|
||||
}
|
||||
|
||||
- (id)initWithColor:(NSColor*)color {
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// IJSVGDef.h
|
||||
// IJSVGExample
|
||||
//
|
||||
// Created by Curtis Hard on 03/09/2014.
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGNode.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface IJSVGDef : NSObject {
|
||||
|
||||
@private
|
||||
NSMutableDictionary* _dict;
|
||||
}
|
||||
|
||||
- (void)addDef:(IJSVGNode*)aDef;
|
||||
- (IJSVGDef*)defForID:(NSString*)anID;
|
||||
|
||||
@end
|
||||
@@ -1,40 +0,0 @@
|
||||
//
|
||||
// IJSVGDef.m
|
||||
// IJSVGExample
|
||||
//
|
||||
// Created by Curtis Hard on 03/09/2014.
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGDef.h"
|
||||
|
||||
@implementation IJSVGDef
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_dict release]), _dict = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
_dict = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)addDef:(IJSVGNode*)aDef
|
||||
{
|
||||
if (aDef.identifier == nil) {
|
||||
return;
|
||||
}
|
||||
_dict[aDef.identifier] = aDef;
|
||||
}
|
||||
|
||||
- (IJSVGDef*)defForID:(NSString*)anID
|
||||
{
|
||||
return _dict[anID];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// IJSVGFilter.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 18/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
|
||||
@interface IJSVGFilter : IJSVGGroup
|
||||
|
||||
- (CGImageRef)newImageByApplyFilterToLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
scale:(CGFloat)scale;
|
||||
|
||||
@property (nonatomic, readonly) BOOL valid;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// IJSVGFilter.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 18/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGFilter.h>
|
||||
#import <IJSVG/IJSVGFilterEffect.h>
|
||||
#import <IJSVG/IJSVGLayer.h>
|
||||
#import <IJSVG/IJSVGThreadManager.h>
|
||||
|
||||
@implementation IJSVGFilter
|
||||
|
||||
- (BOOL)valid
|
||||
{
|
||||
return self.children.count != 0;
|
||||
}
|
||||
|
||||
- (CGImageRef)newImageByApplyFilterToLayer:(CALayer<IJSVGDrawableLayer>*)layer
|
||||
scale:(CGFloat)scale
|
||||
{
|
||||
IJSVGFilter* filter = layer.filter;
|
||||
layer.filter = nil;
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
uint32_t info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little;
|
||||
CGImageRef originalImage = [IJSVGLayer newImageForLayer:layer
|
||||
options:IJSVGLayerDrawingOptionNone
|
||||
colorSpace:colorSpace
|
||||
bitmapInfo:info
|
||||
scale:scale];
|
||||
CIImage* image = [CIImage imageWithCGImage:originalImage];
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
CGImageRelease(originalImage);
|
||||
|
||||
for(IJSVGFilterEffect* effect in self.children) {
|
||||
image = [effect processImage:image];
|
||||
}
|
||||
|
||||
IJSVGThreadManager* manager = IJSVGThreadManager.currentManager;
|
||||
CIContext* context = manager.CIContext;
|
||||
CGImageRef outputImage = [context createCGImage:image
|
||||
fromRect:image.extent];
|
||||
layer.filter = filter;
|
||||
return outputImage;
|
||||
}
|
||||
|
||||
- (void)addChild:(IJSVGNode*)child
|
||||
{
|
||||
if([child isKindOfClass:IJSVGFilterEffect.class] == NO) {
|
||||
return;
|
||||
}
|
||||
[super addChild:child];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// IJSVGFilterEffect.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 18/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, IJSVGFilterEffectSource) {
|
||||
IJSVGFilterEffectSourceGraphic,
|
||||
IJSVGFilterEffectSourceAlpha,
|
||||
IJSVGFilterEffectSourceBackgroundImage,
|
||||
IJSVGFilterEffectSourceBackgroundAlpha,
|
||||
IJSVGFilterEffectSourceFillPaint,
|
||||
IJSVGFilterEffectSourceStrokePaint,
|
||||
IJSVGFilterEffectSourcePrimitiveReference,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, IJSVGFilterEffectEdgeMode) {
|
||||
IJSVGFilterEffectEdgeModeNone,
|
||||
IJSVGFilterEffectEdgeModeWrap,
|
||||
IJSVGFilterEffectEdgeModeDuplicate,
|
||||
};
|
||||
|
||||
@interface IJSVGFilterEffect : IJSVGGroup
|
||||
|
||||
@property (nonatomic, assign) IJSVGFilterEffectSource source;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* stdDeviation;
|
||||
@property (nonatomic, assign) IJSVGFilterEffectEdgeMode edgeMode;
|
||||
@property (nonatomic, copy) NSString* primitiveReference;
|
||||
|
||||
+ (Class)effectClassForElementName:(NSString*)name;
|
||||
+ (IJSVGFilterEffectSource)sourceForString:(NSString*)string;
|
||||
+ (IJSVGFilterEffectEdgeMode)edgeModeForString:(NSString*)string;
|
||||
|
||||
- (CIImage*)processImage:(CIImage*)image;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// IJSVGFilterEffect.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 18/04/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGFilterEffect.h>
|
||||
#import <IJSVG/IJSVGFilterEffectGaussianBlur.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
|
||||
@implementation IJSVGFilterEffect
|
||||
|
||||
static NSDictionary<NSString*, Class>* _elementClassMap = nil;
|
||||
|
||||
+ (void)load
|
||||
{
|
||||
_elementClassMap = @{
|
||||
@"fegaussianblur": IJSVGFilterEffectGaussianBlur.class
|
||||
};
|
||||
}
|
||||
|
||||
+ (Class)effectClassForElementName:(NSString*)name
|
||||
{
|
||||
NSString* key = name.lowercaseString;
|
||||
return _elementClassMap[key] ?: IJSVGFilterEffect.class;
|
||||
}
|
||||
|
||||
+ (IJSVGFilterEffectSource)sourceForString:(NSString*)string
|
||||
{
|
||||
const char* name = string.UTF8String;
|
||||
if(name == NULL) {
|
||||
return IJSVGFilterEffectSourceGraphic;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(name, "sourcegraphic") == YES) {
|
||||
return IJSVGFilterEffectSourceGraphic;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(name, "sourcealpha") == YES) {
|
||||
return IJSVGFilterEffectSourceAlpha;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(name, "backgroundimage") == YES) {
|
||||
return IJSVGFilterEffectSourceBackgroundImage;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(name, "backgroundalpha") == YES) {
|
||||
return IJSVGFilterEffectSourceBackgroundAlpha;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(name, "fillpaint") == YES) {
|
||||
return IJSVGFilterEffectSourceFillPaint;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(name, "strokepain") == YES) {
|
||||
return IJSVGFilterEffectSourceStrokePaint;
|
||||
}
|
||||
return IJSVGFilterEffectSourcePrimitiveReference;
|
||||
}
|
||||
|
||||
+ (IJSVGFilterEffectEdgeMode)edgeModeForString:(NSString*)string
|
||||
{
|
||||
const char* name = string.lowercaseString.UTF8String;
|
||||
if(name == NULL) {
|
||||
return IJSVGFilterEffectEdgeModeNone;
|
||||
}
|
||||
if(IJSVGCharBufferCompare(name, "none") == YES) {
|
||||
return IJSVGFilterEffectEdgeModeNone;
|
||||
}
|
||||
if(IJSVGCharBufferCompare(name, "wrap") == YES) {
|
||||
return IJSVGFilterEffectEdgeModeWrap;
|
||||
}
|
||||
if(IJSVGCharBufferCompare(name, "duplicate") == YES) {
|
||||
return IJSVGFilterEffectEdgeModeDuplicate;
|
||||
}
|
||||
return IJSVGFilterEffectEdgeModeNone;
|
||||
}
|
||||
|
||||
- (CIImage*)processImage:(CIImage*)image
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -6,14 +6,8 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGForeignObject.h"
|
||||
#import <IJSVG/IJSVGForeignObject.h>
|
||||
|
||||
@implementation IJSVGForeignObject
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_requiredExtension release]), _requiredExtension = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,35 +7,27 @@
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <IJSVG/IJSVGColorList.h>
|
||||
#import <IJSVG/IJSVGDef.h>
|
||||
#import <IJSVG/IJSVGTraitedColorStorage.h>
|
||||
#import <IJSVG/IJSVGTransform.h>
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
|
||||
@interface IJSVGGradient : IJSVGGroup
|
||||
|
||||
@property (nonatomic, retain) NSGradient* gradient;
|
||||
@property (nonatomic, strong) NSArray<NSColor*>* colors;
|
||||
@property (nonatomic, assign) CGFloat* locations;
|
||||
@property (nonatomic, assign) NSUInteger numberOfStops;
|
||||
@property (nonatomic, assign) CGGradientRef CGGradient;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* x1;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* x2;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* y1;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* y2;
|
||||
@property (nonatomic, retain) IJSVGColorList* colorList;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* x1;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* x2;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* y1;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* y2;
|
||||
|
||||
+ (CGFloat*)computeColorStops:(IJSVGGradient*)gradient
|
||||
colors:(NSArray**)someColors;
|
||||
|
||||
- (CGGradientRef)CGGradient;
|
||||
- (void)drawInContextRef:(CGContextRef)ctx
|
||||
objectRect:(NSRect)objectRect
|
||||
absoluteTransform:(CGAffineTransform)absoluteTransform
|
||||
viewPort:(CGRect)viewBox;
|
||||
|
||||
- (void)_debugStart:(CGPoint)startPoint
|
||||
end:(CGPoint)endPoint
|
||||
context:(CGContextRef)ctx;
|
||||
|
||||
- (IJSVGColorList*)colorList;
|
||||
- (IJSVGColorList*)computedColorList;
|
||||
bounds:(NSRect)objectRect
|
||||
transform:(CGAffineTransform)absoluteTransform;
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,49 +6,64 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGGradient.h"
|
||||
#import "IJSVGParser.h"
|
||||
#import <IJSVG/IJSVGGradient.h>
|
||||
#import <IJSVG/IJSVGParser.h>
|
||||
|
||||
@implementation IJSVGGradient
|
||||
|
||||
@synthesize colorList = _privateColorList;
|
||||
+ (IJSVGBitFlags*)allowedAttributes
|
||||
{
|
||||
IJSVGBitFlags64* storage = [[IJSVGBitFlags64 alloc] init];
|
||||
[storage addBits:[super allowedAttributes]];
|
||||
[storage setBit:IJSVGNodeAttributeGradientUnits];
|
||||
[storage setBit:IJSVGNodeAttributeGradientTransform];
|
||||
return storage;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_x1 release]), _x1 = nil;
|
||||
(void)([_x2 release]), _x2 = nil;
|
||||
(void)([_y1 release]), _y1 = nil;
|
||||
(void)([_y2 release]), _y2 = nil;
|
||||
(void)([_gradient release]), _gradient = nil;
|
||||
(void)([_privateColorList release]), _privateColorList = nil;
|
||||
if (_CGGradient != nil) {
|
||||
CGGradientRelease(_CGGradient);
|
||||
if(_locations != NULL) {
|
||||
(void)free(_locations), _locations = NULL;
|
||||
}
|
||||
if(_CGGradient != NULL) {
|
||||
(void)CGGradientRelease(_CGGradient), _CGGradient = NULL;
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
IJSVGGradient* clone = [super copyWithZone:zone];
|
||||
clone.gradient = [[self.gradient copy] autorelease];
|
||||
IJSVGGradient* clone = [[self.class alloc] init];
|
||||
[clone applyPropertiesFromNode:self];
|
||||
return clone;
|
||||
}
|
||||
|
||||
- (void)setColorList:(IJSVGColorList*)list
|
||||
- (void)applyPropertiesFromNode:(IJSVGGradient*)node
|
||||
{
|
||||
(void)([_privateColorList release]), _privateColorList = nil;
|
||||
_privateColorList = list.retain;
|
||||
if (_CGGradient != nil) {
|
||||
CGGradientRelease(_CGGradient);
|
||||
_CGGradient = nil;
|
||||
}
|
||||
[super applyPropertiesFromNode:node];
|
||||
self.numberOfStops = node.numberOfStops;
|
||||
self.colors = node.colors.copy;
|
||||
size_t length = sizeof(CGFloat)*node.numberOfStops;
|
||||
self.locations = (CGFloat*)malloc(length);
|
||||
memcpy(self.locations, node.locations, length);
|
||||
self.x1 = node.x1.copy;
|
||||
self.x2 = node.x2.copy;
|
||||
self.y1 = node.y1.copy;
|
||||
self.y2 = node.y2.copy;
|
||||
}
|
||||
|
||||
+ (CGFloat *)computeColorStops:(IJSVGGradient*)gradient
|
||||
colors:(NSArray**)someColors
|
||||
- (void)setLocations:(CGFloat*)locations
|
||||
{
|
||||
if(_locations != NULL) {
|
||||
(void)free(_locations), _locations = NULL;
|
||||
}
|
||||
_locations = locations;
|
||||
}
|
||||
|
||||
+ (CGFloat*)computeColorStops:(IJSVGGradient*)gradient
|
||||
colors:(NSArray**)someColors
|
||||
{
|
||||
NSArray<IJSVGNode*>* stops = gradient.children;
|
||||
NSMutableArray* colors = [[[NSMutableArray alloc] initWithCapacity:stops.count] autorelease];
|
||||
NSMutableArray* colors = [[NSMutableArray alloc] initWithCapacity:stops.count];
|
||||
CGFloat* stopsParams = (CGFloat*)malloc(stops.count * sizeof(CGFloat));
|
||||
|
||||
NSInteger i = 0;
|
||||
@@ -70,73 +85,30 @@
|
||||
return stopsParams;
|
||||
}
|
||||
|
||||
- (IJSVGColorList*)colorList
|
||||
{
|
||||
IJSVGColorList* sheet = [[[IJSVGColorList alloc] init] autorelease];
|
||||
NSInteger num = self.gradient.numberOfColorStops;
|
||||
for (NSInteger i = 0; i < num; i++) {
|
||||
NSColor* color;
|
||||
[self.gradient getColor:&color
|
||||
location:nil
|
||||
atIndex:i];
|
||||
IJSVGColorType* type = [IJSVGColorType typeWithColor:color
|
||||
flags:IJSVGColorTypeFlagStop];
|
||||
[sheet addColor:type];
|
||||
}
|
||||
return sheet;
|
||||
}
|
||||
|
||||
- (IJSVGColorList*)computedColorList
|
||||
{
|
||||
return _privateColorList;
|
||||
}
|
||||
|
||||
- (CGGradientRef)CGGradient
|
||||
{
|
||||
// store it in the cache
|
||||
if (_CGGradient != nil) {
|
||||
if(_CGGradient != nil) {
|
||||
return _CGGradient;
|
||||
}
|
||||
|
||||
// actually create the gradient
|
||||
NSInteger num = self.gradient.numberOfColorStops;
|
||||
CGFloat* locations = (CGFloat*)malloc(sizeof(CGFloat) * num);
|
||||
NSInteger num = self.numberOfStops;
|
||||
CFMutableArrayRef colors = CFArrayCreateMutable(kCFAllocatorDefault, (CFIndex)num,
|
||||
&kCFTypeArrayCallBacks);
|
||||
for (NSInteger i = 0; i < num; i++) {
|
||||
NSColor* color;
|
||||
[self.gradient getColor:&color
|
||||
location:&locations[i]
|
||||
atIndex:i];
|
||||
if (_privateColorList != nil) {
|
||||
color = [_privateColorList proposedColorForColor:color];
|
||||
}
|
||||
for (NSColor* color in _colors) {
|
||||
CFArrayAppendValue(colors, color.CGColor);
|
||||
}
|
||||
CGGradientRef result = CGGradientCreateWithColors(_gradient.colorSpace.CGColorSpace,
|
||||
colors, locations);
|
||||
CGGradientRef result = CGGradientCreateWithColors(IJSVGColor.defaultColorSpace.CGColorSpace,
|
||||
colors, _locations);
|
||||
CFRelease(colors);
|
||||
free(locations);
|
||||
return _CGGradient = result;
|
||||
}
|
||||
|
||||
- (void)drawInContextRef:(CGContextRef)ctx
|
||||
objectRect:(NSRect)objectRect
|
||||
absoluteTransform:(CGAffineTransform)absoluteTransform
|
||||
viewPort:(CGRect)viewBox
|
||||
bounds:(NSRect)objectRect
|
||||
transform:(CGAffineTransform)absoluteTransform
|
||||
{
|
||||
}
|
||||
|
||||
- (void)_debugStart:(CGPoint)startPoint
|
||||
end:(CGPoint)endPoint
|
||||
context:(CGContextRef)ctx
|
||||
{
|
||||
CGContextSaveGState(ctx);
|
||||
CGContextSetStrokeColorWithColor(ctx, NSColor.blackColor.CGColor);
|
||||
CGContextSetLineWidth(ctx, 1.f);
|
||||
CGContextMoveToPoint(ctx, startPoint.x, startPoint.y);
|
||||
CGContextAddLineToPoint(ctx, endPoint.x, endPoint.y);
|
||||
CGContextStrokePath(ctx);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -16,8 +16,15 @@
|
||||
NSMutableArray<IJSVGNode*>* _children;
|
||||
}
|
||||
|
||||
@property (nonatomic, readonly) NSArray<IJSVGNode*>* children;
|
||||
@property (weak, nonatomic, readonly) NSArray<IJSVGNode*>* children;
|
||||
|
||||
- (void)addChild:(IJSVGNode*)child;
|
||||
- (void)addChildren:(NSArray<IJSVGNode*>*)children;
|
||||
- (void)removeChild:(IJSVGNode*)child;
|
||||
- (void)removeChildren:(NSArray<IJSVGNode*>*)children;
|
||||
- (BOOL)childrenMatchTraits:(IJSVGNodeTraits)traits;
|
||||
- (BOOL)containsNodesMatchingTraits:(IJSVGNodeTraits)traits;
|
||||
- (NSArray<IJSVGNode*>*)nodesMatchingTraits:(IJSVGNodeTraits)traits;
|
||||
- (NSSet<IJSVGNode*>*)childrenOfType:(IJSVGNodeType)type;
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,29 +6,30 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGGroup.h"
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
#import <IJSVG/IJSVGImage.h>
|
||||
|
||||
@implementation IJSVGGroup
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)([_children release]), _children = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
if((self = [super init]) != nil) {
|
||||
_children = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (IJSVGBitFlags*)allowedAttributes
|
||||
{
|
||||
IJSVGBitFlags64* storage = [[IJSVGBitFlags64 alloc] init];
|
||||
[storage addBits:[super allowedAttributes]];
|
||||
[storage addBits:[IJSVGPath allowedAttributes]];
|
||||
[storage addBits:[IJSVGImage allowedAttributes]];
|
||||
return storage;
|
||||
}
|
||||
|
||||
- (void)prepareFromCopy
|
||||
{
|
||||
if(_children != nil) {
|
||||
(void)[_children release], _children = nil;
|
||||
}
|
||||
_children = [[NSMutableArray alloc] init];
|
||||
}
|
||||
|
||||
@@ -37,8 +38,8 @@
|
||||
IJSVGGroup* node = [super copyWithZone:zone];
|
||||
[node prepareFromCopy];
|
||||
|
||||
for (IJSVGNode* childNode in _children) {
|
||||
childNode = [[childNode copy] autorelease];
|
||||
for (__strong IJSVGNode* childNode in _children) {
|
||||
childNode = childNode.copy;
|
||||
childNode.parentNode = node;
|
||||
[node addChild:childNode];
|
||||
}
|
||||
@@ -47,7 +48,8 @@
|
||||
|
||||
- (void)addChild:(IJSVGNode*)child
|
||||
{
|
||||
if(child == nil || (child.parentNode == self && [_children containsObject:child])) {
|
||||
if(child == nil || child == self ||
|
||||
(child.parentNode == self && [_children containsObject:child])) {
|
||||
return;
|
||||
}
|
||||
child.parentNode = self;
|
||||
@@ -62,11 +64,62 @@
|
||||
[_children removeObject:child];
|
||||
}
|
||||
|
||||
- (void)addChildren:(NSArray<IJSVGNode*>*)children
|
||||
{
|
||||
for(IJSVGNode* node in children) {
|
||||
[self addChild:node];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeChildren:(NSArray<IJSVGNode*>*)children
|
||||
{
|
||||
for(IJSVGNode* node in children) {
|
||||
[self removeChild:node];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)childrenMatchTraits:(IJSVGNodeTraits)traits
|
||||
{
|
||||
for(IJSVGNode* node in _children) {
|
||||
if([node matchesTraits:traits] == NO) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSSet<IJSVGNode*>*)childrenOfType:(IJSVGNodeType)type
|
||||
{
|
||||
NSMutableSet<IJSVGNode*>* nodes = [[NSMutableSet alloc] init];
|
||||
for(IJSVGNode* node in self.children) {
|
||||
if(node.type == type) {
|
||||
[nodes addObject:node];
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
- (BOOL)containsNodesMatchingTraits:(IJSVGNodeTraits)traits
|
||||
{
|
||||
return [self.class node:self
|
||||
containsNodesMatchingTraits:traits];
|
||||
}
|
||||
|
||||
- (NSArray<IJSVGNode*>*)nodesMatchingTraits:(IJSVGNodeTraits)traits
|
||||
{
|
||||
return [self.class node:self
|
||||
nodesMatchingTraits:traits];
|
||||
}
|
||||
|
||||
- (CGRect)bounds
|
||||
{
|
||||
CGRect rect = CGRectZero;
|
||||
CGRect rect = CGRectNull;
|
||||
for(IJSVGNode* node in self.children) {
|
||||
rect = CGRectUnion(rect, node.bounds);
|
||||
if(CGRectIsNull(rect)) {
|
||||
rect = node.bounds;
|
||||
} else {
|
||||
rect = CGRectUnion(rect, node.bounds);
|
||||
}
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
|
||||
@property (nonatomic, readonly) CGSize intrinsicSize;
|
||||
@property (nonatomic, readonly) CGRect intrinsicBounds;
|
||||
@property (nonatomic, readonly) CGAffineTransform intrinsicTransform;
|
||||
@property (nonatomic, retain) NSImage* image;
|
||||
@property (nonatomic, strong) NSImage* image;
|
||||
|
||||
- (CGImageRef)CGImage;
|
||||
- (void)loadFromString:(NSString*)encodedString;
|
||||
|
||||
@@ -6,22 +6,39 @@
|
||||
// Copyright © 2016 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGImage.h"
|
||||
#import "IJSVGPath.h"
|
||||
#import "IJSVGTransform.h"
|
||||
#import <IJSVG/IJSVGImage.h>
|
||||
#import <IJSVG/IJSVGPath.h>
|
||||
#import <IJSVG/IJSVGTransform.h>
|
||||
|
||||
@implementation IJSVGImage
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)(CGImageRelease(CGImage)), CGImage = nil;
|
||||
(void)([_image release]), _image = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
+ (IJSVGBitFlags*)allowedAttributes
|
||||
{
|
||||
IJSVGBitFlags64* storage = [[IJSVGBitFlags64 alloc] init];
|
||||
[storage addBits:[super allowedAttributes]];
|
||||
[storage setBit:IJSVGNodeAttributeX];
|
||||
[storage setBit:IJSVGNodeAttributeY];
|
||||
[storage setBit:IJSVGNodeAttributeWidth];
|
||||
[storage setBit:IJSVGNodeAttributeHeight];
|
||||
[storage setBit:IJSVGNodeAttributePreserveAspectRatio];
|
||||
return storage;
|
||||
}
|
||||
|
||||
- (void)setDefaults
|
||||
{
|
||||
[super setDefaults];
|
||||
self.viewBoxAlignment = IJSVGViewBoxAlignmentXMidYMid;
|
||||
self.viewBoxMeetOrSlice = IJSVGViewBoxMeetOrSliceMeet;
|
||||
}
|
||||
|
||||
- (void)loadFromString:(NSString*)encodedString
|
||||
{
|
||||
if ([encodedString hasPrefix:@"data:"]) {
|
||||
if([encodedString hasPrefix:@"data:"]) {
|
||||
encodedString = [encodedString stringByReplacingOccurrencesOfString:@"\\s+"
|
||||
withString:@""
|
||||
options:NSRegularExpressionSearch
|
||||
@@ -38,29 +55,28 @@
|
||||
NSData* data = [NSData dataWithContentsOfURL:aURL];
|
||||
|
||||
// no data, just ignore...invalid probably
|
||||
if (data == nil) {
|
||||
if(data == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set the image against the container
|
||||
NSImage* anImage = [[[NSImage alloc] initWithData:data] autorelease];
|
||||
NSImage* anImage = [[NSImage alloc] initWithData:data];
|
||||
[self setImage:anImage];
|
||||
}
|
||||
|
||||
- (void)setImage:(NSImage*)anImage
|
||||
{
|
||||
if (_image != nil) {
|
||||
(void)([_image release]), _image = nil;
|
||||
}
|
||||
_image = [anImage retain];
|
||||
_image = anImage;
|
||||
_intrinsicSize = (CGSize)_image.size;
|
||||
|
||||
if (CGImage != nil) {
|
||||
if(CGImage != nil) {
|
||||
CGImageRelease(CGImage);
|
||||
CGImage = nil;
|
||||
}
|
||||
|
||||
NSRect rect = NSMakeRect(0.f, 0.f, _intrinsicSize.width, _intrinsicSize.height);
|
||||
CGRect rect = CGRectMake(0.f, 0.f,
|
||||
_intrinsicSize.width,
|
||||
_intrinsicSize.height);
|
||||
CGImage = [_image CGImageForProposedRect:&rect
|
||||
context:nil
|
||||
hints:nil];
|
||||
@@ -81,13 +97,6 @@
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (CGAffineTransform)intrinsicTransform
|
||||
{
|
||||
CGFloat widthRatio = self.width.value / _intrinsicSize.width;
|
||||
CGFloat heightRatio = self.height.value / _intrinsicSize.height;
|
||||
return CGAffineTransformMakeScale(widthRatio, heightRatio);
|
||||
}
|
||||
|
||||
- (CGRect)bounds
|
||||
{
|
||||
return CGRectMake(0.f, 0.f,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
@interface IJSVGLinearGradient : IJSVGGradient
|
||||
|
||||
+ (NSGradient*)parseGradient:(NSXMLElement*)element
|
||||
gradient:(IJSVGLinearGradient*)aGradient;
|
||||
+ (void)parseGradient:(NSXMLElement*)element
|
||||
gradient:(IJSVGLinearGradient*)aGradient;
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,14 +6,25 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGLinearGradient.h"
|
||||
#import "IJSVGUtils.h"
|
||||
#import "IJSVGParser.h"
|
||||
#import <IJSVG/IJSVGLinearGradient.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
#import <IJSVG/IJSVGParser.h>
|
||||
|
||||
@implementation IJSVGLinearGradient
|
||||
|
||||
+ (NSGradient*)parseGradient:(NSXMLElement*)element
|
||||
gradient:(IJSVGLinearGradient*)aGradient
|
||||
+ (IJSVGBitFlags*)allowedAttributes
|
||||
{
|
||||
IJSVGBitFlags64* storage = [[IJSVGBitFlags64 alloc] init];
|
||||
[storage addBits:[super allowedAttributes]];
|
||||
[storage setBit:IJSVGNodeAttributeX1];
|
||||
[storage setBit:IJSVGNodeAttributeX2];
|
||||
[storage setBit:IJSVGNodeAttributeY1];
|
||||
[storage setBit:IJSVGNodeAttributeY2];
|
||||
return storage;
|
||||
}
|
||||
|
||||
+ (void)parseGradient:(NSXMLElement*)element
|
||||
gradient:(IJSVGLinearGradient*)aGradient
|
||||
{
|
||||
// just ask unit for the value
|
||||
NSString* x1 = ([element attributeForName:IJSVGAttributeX1].stringValue ?: @"0");
|
||||
@@ -29,57 +40,48 @@
|
||||
NSArray* colors = nil;
|
||||
CGFloat* stopsParams = [self.class computeColorStops:aGradient
|
||||
colors:&colors];
|
||||
|
||||
// create the gradient with the colours
|
||||
NSGradient* grad = [[NSGradient alloc] initWithColors:colors
|
||||
atLocations:stopsParams
|
||||
colorSpace:IJSVGColor.defaultColorSpace];
|
||||
|
||||
free(stopsParams);
|
||||
return [grad autorelease];
|
||||
aGradient.colors = colors;
|
||||
aGradient.locations = stopsParams;
|
||||
aGradient.numberOfStops = colors.count;
|
||||
}
|
||||
|
||||
- (void)drawInContextRef:(CGContextRef)ctx
|
||||
objectRect:(NSRect)objectRect
|
||||
absoluteTransform:(CGAffineTransform)absoluteTransform
|
||||
viewPort:(CGRect)viewBox
|
||||
bounds:(NSRect)objectRect
|
||||
transform:(CGAffineTransform)absoluteTransform
|
||||
{
|
||||
BOOL inUserSpace = self.units == IJSVGUnitUserSpaceOnUse;
|
||||
|
||||
CGPoint gradientStartPoint = CGPointZero;
|
||||
CGPoint gradientEndPoint = CGPointZero;
|
||||
CGAffineTransform selfTransform = IJSVGConcatTransforms(self.transforms);
|
||||
|
||||
CGRect boundingBox = inUserSpace ? viewBox : objectRect;
|
||||
CGRect boundingBox = objectRect;
|
||||
|
||||
// make sure we apply the absolute position to
|
||||
// transform us back into the correct space
|
||||
if (inUserSpace == YES) {
|
||||
CGContextConcatCTM(ctx, absoluteTransform);
|
||||
}
|
||||
|
||||
CGFloat width = CGRectGetWidth(boundingBox);
|
||||
CGFloat height = CGRectGetHeight(boundingBox);
|
||||
gradientStartPoint = CGPointMake([self.x1 computeValue:width],
|
||||
[self.y1 computeValue:height]);
|
||||
|
||||
gradientEndPoint = CGPointMake([self.x2 computeValue:width],
|
||||
[self.y2 computeValue:height]);
|
||||
|
||||
// transform the context
|
||||
CGContextConcatCTM(ctx, selfTransform);
|
||||
|
||||
if(inUserSpace == YES) {
|
||||
CGContextConcatCTM(ctx, absoluteTransform);
|
||||
} else {
|
||||
width = 1.f;
|
||||
height = 1.f;
|
||||
CGContextConcatCTM(ctx, CGAffineTransformMakeScale(boundingBox.size.width,
|
||||
boundingBox.size.height));
|
||||
}
|
||||
|
||||
gradientStartPoint = CGPointMake([self.x1 computeValue:width],
|
||||
[self.y1 computeValue:height]);
|
||||
gradientEndPoint = CGPointMake([self.x2 computeValue:width],
|
||||
[self.y2 computeValue:height]);
|
||||
|
||||
// concat the gradient transform into the context
|
||||
IJSVGConcatTransformsCTM(ctx, self.transforms);
|
||||
|
||||
// draw the gradient
|
||||
CGGradientDrawingOptions options = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
|
||||
|
||||
CGContextDrawLinearGradient(ctx, self.CGGradient, gradientStartPoint,
|
||||
gradientEndPoint, options);
|
||||
|
||||
#ifdef IJSVG_DEBUG
|
||||
[self _debugStart:gradientStartPoint
|
||||
end:gradientEndPoint
|
||||
context:ctx];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// IJSVGMask.h
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 28/05/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
|
||||
@interface IJSVGMask : IJSVGGroup
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// IJSVGMask.m
|
||||
// IJSVG
|
||||
//
|
||||
// Created by Curtis Hard on 28/05/2022.
|
||||
// Copyright © 2022 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGMask.h>
|
||||
#import <IJSVG/IJSVGRootNode.h>
|
||||
|
||||
@implementation IJSVGMask
|
||||
|
||||
+ (IJSVGBitFlags*)allowedAttributes
|
||||
{
|
||||
IJSVGBitFlags64* storage = [[IJSVGBitFlags64 alloc] init];
|
||||
[storage addBits:[super allowedAttributes]];
|
||||
[storage setBit:IJSVGNodeAttributeX];
|
||||
[storage setBit:IJSVGNodeAttributeY];
|
||||
[storage setBit:IJSVGNodeAttributeWidth];
|
||||
[storage setBit:IJSVGNodeAttributeHeight];
|
||||
[storage setBit:IJSVGNodeAttributeMaskUnits];
|
||||
[storage setBit:IJSVGNodeAttributeMaskContentUnits];
|
||||
return storage;
|
||||
}
|
||||
|
||||
- (void)setDefaults
|
||||
{
|
||||
[super setDefaults];
|
||||
self.x = [IJSVGUnitLength unitWithPercentageFloat:-.2f];
|
||||
self.y = [IJSVGUnitLength unitWithPercentageFloat:-.2f];
|
||||
self.width = [IJSVGUnitLength unitWithPercentageFloat:1.2f];
|
||||
self.height = [IJSVGUnitLength unitWithPercentageFloat:1.2f];
|
||||
self.units = IJSVGUnitObjectBoundingBox;
|
||||
self.contentUnits = IJSVGUnitUserSpaceOnUse;
|
||||
self.overflowVisibility = IJSVGOverflowVisibilityHidden;
|
||||
}
|
||||
|
||||
- (IJSVGUnitType)contentUnitsWithReferencingNodeBounds:(CGRect *)bounds
|
||||
{
|
||||
IJSVGNode* node = nil;
|
||||
IJSVGUnitType units = [self contentUnitsWithReferencingNode:&node];
|
||||
if(units == IJSVGUnitUserSpaceOnUse) {
|
||||
*bounds = node.rootNode.bounds;
|
||||
} else {
|
||||
*bounds = node.parentNode.bounds;
|
||||
}
|
||||
return units;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -6,9 +6,10 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGStyle.h>
|
||||
#import <IJSVG/IJSVGStyleSheetStyle.h>
|
||||
#import <IJSVG/IJSVGUnitLength.h>
|
||||
#import <IJSVG/IJSVGViewBox.h>
|
||||
#import <IJSVG/IJSVGBitFlags64.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -21,16 +22,98 @@
|
||||
@class IJSVGTransform;
|
||||
@class IJSVGRootNode;
|
||||
@class IJSVGUnitRect;
|
||||
@class IJSVGFilter;
|
||||
@class IJSVGMask;
|
||||
@class IJSVGClipPath;
|
||||
@class IJSVGThreadManager;
|
||||
|
||||
typedef void (^IJSVGNodeWalkHandler)(IJSVGNode* node, BOOL* allowChildNodes, BOOL* stop);
|
||||
|
||||
typedef NS_ENUM(NSInteger, IJSVGNodeAttribute) {
|
||||
IJSVGNodeAttributeVersion,
|
||||
IJSVGNodeAttributeXMLNS,
|
||||
IJSVGNodeAttributeXMLNSXlink,
|
||||
IJSVGNodeAttributeViewBox,
|
||||
IJSVGNodeAttributePreserveAspectRatio,
|
||||
IJSVGNodeAttributeID,
|
||||
IJSVGNodeAttributeClass,
|
||||
IJSVGNodeAttributeX,
|
||||
IJSVGNodeAttributeY,
|
||||
IJSVGNodeAttributeWidth,
|
||||
IJSVGNodeAttributeHeight,
|
||||
IJSVGNodeAttributeOpacity,
|
||||
IJSVGNodeAttributeStrokeOpacity,
|
||||
IJSVGNodeAttributeStrokeWidth,
|
||||
IJSVGNodeAttributeStrokeDashOffset,
|
||||
IJSVGNodeAttributeFillOpacity,
|
||||
IJSVGNodeAttributeClipPath,
|
||||
IJSVGNodeAttributeClipPathUnits,
|
||||
IJSVGNodeAttributeClipRule,
|
||||
IJSVGNodeAttributeMask,
|
||||
IJSVGNodeAttributeGradientUnits,
|
||||
IJSVGNodeAttributePatternUnits,
|
||||
IJSVGNodeAttributePatternContentUnits,
|
||||
IJSVGNodeAttributePatternTransform,
|
||||
IJSVGNodeAttributeMaskUnits,
|
||||
IJSVGNodeAttributeMaskContentUnits,
|
||||
IJSVGNodeAttributeTransform,
|
||||
IJSVGNodeAttributeGradientTransform,
|
||||
IJSVGNodeAttributeUnicode,
|
||||
IJSVGNodeAttributeStrokeLineCap,
|
||||
IJSVGNodeAttributeStrokeLineJoin,
|
||||
IJSVGNodeAttributeStroke,
|
||||
IJSVGNodeAttributeStrokeDashArray,
|
||||
IJSVGNodeAttributeStrokeMiterLimit,
|
||||
IJSVGNodeAttributeFill,
|
||||
IJSVGNodeAttributeFillRule,
|
||||
IJSVGNodeAttributeBlendMode,
|
||||
IJSVGNodeAttributeDisplay,
|
||||
IJSVGNodeAttributeStyle,
|
||||
IJSVGNodeAttributeD,
|
||||
IJSVGNodeAttributeXLink,
|
||||
IJSVGNodeAttributeX1,
|
||||
IJSVGNodeAttributeX2,
|
||||
IJSVGNodeAttributeY1,
|
||||
IJSVGNodeAttributeY2,
|
||||
IJSVGNodeAttributeRX,
|
||||
IJSVGNodeAttributeRY,
|
||||
IJSVGNodeAttributeCX,
|
||||
IJSVGNodeAttributeCY,
|
||||
IJSVGNodeAttributeR,
|
||||
IJSVGNodeAttributeFX,
|
||||
IJSVGNodeAttributeFY,
|
||||
IJSVGNodeAttributeFR,
|
||||
IJSVGNodeAttributePoints,
|
||||
IJSVGNodeAttributeOffset,
|
||||
IJSVGNodeAttributeStopColor,
|
||||
IJSVGNodeAttributeStopOpacity,
|
||||
IJSVGNodeAttributeHref,
|
||||
IJSVGNodeAttributeOverflow,
|
||||
IJSVGNodeAttributeFilter,
|
||||
IJSVGNodeAttributeStdDeviation,
|
||||
IJSVGNodeAttributeIn,
|
||||
IJSVGNodeAttributeEdgeMode,
|
||||
IJSVGNodeAttributeMarker
|
||||
};
|
||||
|
||||
static const int kIJSVGNodeAttributeStorageLength = 64;
|
||||
|
||||
typedef NS_OPTIONS(NSInteger, IJSVGIntrinsicDimensions) {
|
||||
IJSVGIntrinsicDimensionNone = 0,
|
||||
IJSVGIntrinsicDimensionWidth = 1 << 1,
|
||||
IJSVGIntrinsicDimensionHeight = 1 << 2,
|
||||
IJSVGIntrinsicDimensionBoth = IJSVGIntrinsicDimensionWidth | IJSVGIntrinsicDimensionHeight
|
||||
};
|
||||
|
||||
typedef NS_OPTIONS(NSInteger, IJSVGNodeTraits) {
|
||||
IJSVGNodeTraitNone = 0,
|
||||
IJSVGNodeTraitStroked = 1 << 0,
|
||||
IJSVGNodeTraitPaintable = 1 << 1
|
||||
IJSVGNodeTraitPaintable = 1 << 1,
|
||||
IJSVGNodeTraitPathed = 1 << 2
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, IJSVGNodeType) {
|
||||
IJSVGNodeTypeUnknown = 0,
|
||||
IJSVGNodeTypeGroup,
|
||||
IJSVGNodeTypePath,
|
||||
IJSVGNodeTypeDef,
|
||||
@@ -58,7 +141,9 @@ typedef NS_ENUM(NSInteger, IJSVGNodeType) {
|
||||
IJSVGNodeTypeDesc,
|
||||
IJSVGNodeTypeStop,
|
||||
IJSVGNodeTypeNotFound,
|
||||
IJSVGNodeTypeUnknown,
|
||||
IJSVGNodeTypeFilter,
|
||||
IJSVGNodeTypeFilterEffect,
|
||||
IJSVGNodeTypeForeignObject
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, IJSVGWindingRule) {
|
||||
@@ -114,14 +199,18 @@ typedef NS_ENUM(NSInteger, IJSVGOverflowVisibility) {
|
||||
};
|
||||
|
||||
static CGFloat IJSVGInheritedFloatValue = -99.9999991;
|
||||
static CGFloat IJSVGInheritedIntegerValue = INT_MIN;
|
||||
|
||||
@interface IJSVGNode : NSObject <NSCopying>
|
||||
@interface IJSVGNode : NSObject <NSCopying> {
|
||||
@private
|
||||
BOOL _computedTraits;
|
||||
}
|
||||
|
||||
void IJSVGAssertPaintableObject(id object);
|
||||
|
||||
@property (nonatomic, assign) IJSVGNodeTraits traits;
|
||||
@property (nonatomic, assign, readonly) CGRect bounds;
|
||||
@property (nonatomic, retain) IJSVGUnitRect* viewBox;
|
||||
@property (nonatomic, strong) IJSVGUnitRect* viewBox;
|
||||
@property (nonatomic, assign) IJSVGViewBoxAlignment viewBoxAlignment;
|
||||
@property (nonatomic, assign) IJSVGViewBoxMeetOrSlice viewBoxMeetOrSlice;
|
||||
@property (nonatomic, copy) NSString* title;
|
||||
@@ -129,44 +218,61 @@ void IJSVGAssertPaintableObject(id object);
|
||||
@property (nonatomic, assign) IJSVGNodeType type;
|
||||
@property (nonatomic, copy) NSString* name;
|
||||
@property (nonatomic, copy) NSString* className;
|
||||
@property (nonatomic, retain) NSArray* classNameList;
|
||||
@property (nonatomic, strong) NSSet<NSString*>* classNameList;
|
||||
@property (nonatomic, copy) NSString* unicode;
|
||||
@property (nonatomic, assign) BOOL shouldRender;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* x;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* y;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* width;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* height;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* opacity;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* fillOpacity;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* strokeOpacity;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* strokeWidth;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* offset;
|
||||
@property (nonatomic, retain) IJSVGNode* fill;
|
||||
@property (nonatomic, retain) IJSVGNode* stroke;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* x;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* y;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* width;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* height;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* opacity;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* fillOpacity;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* strokeOpacity;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* strokeWidth;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* offset;
|
||||
@property (nonatomic, strong) IJSVGNode* fill;
|
||||
@property (nonatomic, strong) IJSVGNode* stroke;
|
||||
@property (nonatomic, copy) NSString* identifier;
|
||||
@property (nonatomic, assign) IJSVGNode* parentNode;
|
||||
@property (nonatomic, retain) IJSVGGroup* clipPath;
|
||||
@property (nonatomic, retain) IJSVGGroup* mask;
|
||||
@property (nonatomic, strong) IJSVGClipPath* clipPath;
|
||||
@property (nonatomic, strong) IJSVGMask* mask;
|
||||
@property (nonatomic, assign) IJSVGWindingRule windingRule;
|
||||
@property (nonatomic, assign) IJSVGWindingRule clipRule;
|
||||
@property (nonatomic, assign) IJSVGLineCapStyle lineCapStyle;
|
||||
@property (nonatomic, assign) IJSVGLineJoinStyle lineJoinStyle;
|
||||
@property (nonatomic, retain) NSArray<IJSVGTransform*>* transforms;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* strokeMiterLimit;
|
||||
@property (nonatomic, strong) NSArray<IJSVGTransform*>* transforms;
|
||||
@property (nonatomic, strong) IJSVGFilter* filter;
|
||||
@property (nonatomic, assign) CGFloat* strokeDashArray;
|
||||
@property (nonatomic, assign) NSInteger strokeDashArrayCount;
|
||||
@property (nonatomic, readonly) NSArray<NSNumber*>* lineDashPattern;
|
||||
@property (nonatomic, retain) IJSVGUnitLength* strokeDashOffset;
|
||||
@property (nonatomic, retain) IJSVG* svg;
|
||||
@property (nonatomic, strong) IJSVGUnitLength* strokeDashOffset;
|
||||
@property (nonatomic, strong) IJSVG* svg;
|
||||
@property (nonatomic, assign) IJSVGUnitType contentUnits;
|
||||
@property (nonatomic, assign) IJSVGUnitType units;
|
||||
@property (nonatomic, assign) IJSVGBlendMode blendMode;
|
||||
@property (nonatomic, assign) IJSVGOverflowVisibility overflowVisibility;
|
||||
@property (nonatomic, readonly) BOOL detachedFromParentNode;
|
||||
@property (nonatomic, readonly) IJSVGRootNode* rootNode;
|
||||
|
||||
+ (IJSVGBitFlags*)computedAllowedAttributes;
|
||||
+ (IJSVGBitFlags*)allowedAttributes;
|
||||
|
||||
+ (void)walkNodeTree:(IJSVGNode*)node
|
||||
handler:(IJSVGNodeWalkHandler)handler;
|
||||
handler:(IJSVGNodeWalkHandler)handler;
|
||||
|
||||
+ (NSArray<IJSVGNode*>*)node:(IJSVGNode*)node
|
||||
nodesMatchingTraits:(IJSVGNodeTraits)traits;
|
||||
|
||||
+ (BOOL)node:(IJSVGNode*)node
|
||||
containsNodesMatchingTraits:(IJSVGNodeTraits)traits;
|
||||
|
||||
+ (IJSVGNodeType)typeForString:(NSString*)string
|
||||
kind:(NSXMLNodeKind)kind;
|
||||
+ (BOOL)typeIsPathable:(IJSVGNodeType)type;
|
||||
|
||||
- (void)setDefaults;
|
||||
- (void)postProcess;
|
||||
- (void)applyPropertiesFromNode:(IJSVGNode*)node;
|
||||
|
||||
- (IJSVGUnitType)contentUnitsWithReferencingNodeBounds:(CGRect*)bounds;
|
||||
@@ -179,4 +285,9 @@ void IJSVGAssertPaintableObject(id object);
|
||||
- (BOOL)matchesTraits:(IJSVGNodeTraits)traits;
|
||||
- (void)computeTraits;
|
||||
|
||||
- (NSSet<IJSVGNode*>*)nodesMatchingTypes:(NSIndexSet*)types;
|
||||
|
||||
- (instancetype)parentNodeMatchingClass:(Class)someClass;
|
||||
- (instancetype)rootNodeMatchingClass:(Class)someClass;
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGDef.h>
|
||||
#import <IJSVG/IJSVGNode.h>
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
#import <IJSVG/IJSVGUtils.h>
|
||||
#import <IJSVG/IJSVGRootNode.h>
|
||||
#import <IJSVG/IJSVGThreadManager.h>
|
||||
|
||||
@implementation IJSVGNode
|
||||
|
||||
@@ -18,127 +19,151 @@
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
(void)free(_strokeDashArray), _strokeDashArray = NULL;
|
||||
(void)([_x release]), _x = nil;
|
||||
(void)([_y release]), _y = nil;
|
||||
(void)([_width release]), _width = nil;
|
||||
(void)([_height release]), _height = nil;
|
||||
(void)([_opacity release]), _opacity = nil;
|
||||
(void)([_offset release]), _offset = nil;
|
||||
(void)([_fillOpacity release]), _fillOpacity = nil;
|
||||
(void)([_strokeOpacity release]), _strokeOpacity = nil;
|
||||
(void)([_strokeWidth release]), _strokeWidth = nil;
|
||||
(void)([_strokeDashOffset release]), _strokeDashOffset = nil;
|
||||
(void)([_unicode release]), _unicode = nil;
|
||||
(void)([_fill release]), _fill = nil;
|
||||
(void)([_stroke release]), _stroke = nil;
|
||||
(void)([_transforms release]), _transforms = nil;
|
||||
(void)([_identifier release]), _identifier = nil;
|
||||
(void)([_name release]), _name = nil;
|
||||
(void)([_title release]), _title = nil;
|
||||
(void)([_desc release]), _desc = nil;
|
||||
(void)([_className release]), _className = nil;
|
||||
(void)([_classNameList release]), _classNameList = nil;
|
||||
(void)([_clipPath release]), _clipPath = nil;
|
||||
(void)([_svg release]), _svg = nil;
|
||||
(void)([_mask release]), _mask = nil;
|
||||
(void)([_viewBox release]), _viewBox = nil;
|
||||
[super dealloc];
|
||||
if(_strokeDashArray != NULL) {
|
||||
(void)free(_strokeDashArray), _strokeDashArray = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+ (IJSVGNodeType)typeForString:(NSString*)string
|
||||
kind:(NSXMLNodeKind)kind
|
||||
{
|
||||
// possible fix for older os's that complain
|
||||
if(string == nil || kind == NSXMLCommentKind) {
|
||||
// if string is nil, or its not a generic element or some text span
|
||||
if(string == nil || (kind != NSXMLElementKind && kind != NSXMLTextKind)) {
|
||||
return IJSVGNodeTypeNotFound;
|
||||
}
|
||||
|
||||
const char* name = string.lowercaseString.UTF8String;
|
||||
if(name == NULL) {
|
||||
const char* nodeType = string.UTF8String;
|
||||
if(nodeType == NULL) {
|
||||
return IJSVGNodeTypeNotFound;
|
||||
}
|
||||
if (strcmp(name, "style") == 0) {
|
||||
return IJSVGNodeTypeStyle;
|
||||
}
|
||||
if (strcmp(name, "switch") == 0) {
|
||||
return IJSVGNodeTypeSwitch;
|
||||
}
|
||||
if (strcmp(name, "defs") == 0) {
|
||||
return IJSVGNodeTypeDef;
|
||||
}
|
||||
if (strcmp(name, "g") == 0) {
|
||||
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "g") == YES) {
|
||||
return IJSVGNodeTypeGroup;
|
||||
}
|
||||
if (strcmp(name, "path") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "path") == YES) {
|
||||
return IJSVGNodeTypePath;
|
||||
}
|
||||
if (strcmp(name, "polygon") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "style") == YES) {
|
||||
return IJSVGNodeTypeStyle;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "switch") == YES) {
|
||||
return IJSVGNodeTypeSwitch;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "defs") == YES) {
|
||||
return IJSVGNodeTypeDef;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "polygon") == YES) {
|
||||
return IJSVGNodeTypePolygon;
|
||||
}
|
||||
if (strcmp(name, "polyline") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "polyline") == YES) {
|
||||
return IJSVGNodeTypePolyline;
|
||||
}
|
||||
if (strcmp(name, "rect") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "rect") == YES) {
|
||||
return IJSVGNodeTypeRect;
|
||||
}
|
||||
if (strcmp(name, "line") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "line") == YES) {
|
||||
return IJSVGNodeTypeLine;
|
||||
}
|
||||
if (strcmp(name, "circle") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "circle") == YES) {
|
||||
return IJSVGNodeTypeCircle;
|
||||
}
|
||||
if (strcmp(name, "ellipse") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "ellipse") == YES) {
|
||||
return IJSVGNodeTypeEllipse;
|
||||
}
|
||||
if (strcmp(name, "use") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "use") == YES) {
|
||||
return IJSVGNodeTypeUse;
|
||||
}
|
||||
if (strcmp(name, "lineargradient") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "lineargradient") == YES) {
|
||||
return IJSVGNodeTypeLinearGradient;
|
||||
}
|
||||
if (strcmp(name, "radialgradient") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "radialgradient") == YES) {
|
||||
return IJSVGNodeTypeRadialGradient;
|
||||
}
|
||||
if(strcmp(name, "stop") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "stop") == YES) {
|
||||
return IJSVGNodeTypeStop;
|
||||
}
|
||||
if (strcmp(name, "glyph") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "glyph") == YES) {
|
||||
return IJSVGNodeTypeGlyph;
|
||||
}
|
||||
if (strcmp(name, "font") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "font") == YES) {
|
||||
return IJSVGNodeTypeFont;
|
||||
}
|
||||
if (strcmp(name, "clippath") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "clippath") == YES) {
|
||||
return IJSVGNodeTypeClipPath;
|
||||
}
|
||||
if (strcmp(name, "mask") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "mask") == YES) {
|
||||
return IJSVGNodeTypeMask;
|
||||
}
|
||||
if (strcmp(name, "image") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "image") == YES) {
|
||||
return IJSVGNodeTypeImage;
|
||||
}
|
||||
if (strcmp(name, "pattern") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "pattern") == YES) {
|
||||
return IJSVGNodeTypePattern;
|
||||
}
|
||||
if (strcmp(name, "svg") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "svg") == YES) {
|
||||
return IJSVGNodeTypeSVG;
|
||||
}
|
||||
if (strcmp(name, "text") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "text") == YES) {
|
||||
return IJSVGNodeTypeText;
|
||||
}
|
||||
if (strcmp(name, "tspan") == 0 || kind == NSXMLTextKind) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "tspan") == YES || kind == NSXMLTextKind) {
|
||||
return IJSVGNodeTypeTextSpan;
|
||||
}
|
||||
if(strcmp(name, "title") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "title") == YES) {
|
||||
return IJSVGNodeTypeTitle;
|
||||
}
|
||||
if(strcmp(name, "desc") == 0) {
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "desc") == YES) {
|
||||
return IJSVGNodeTypeDesc;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "foreignobject") == YES) {
|
||||
return IJSVGNodeTypeForeignObject;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "filter") == YES) {
|
||||
return IJSVGNodeTypeFilter;
|
||||
}
|
||||
if(IJSVGCharBufferCaseInsensitiveCompare(nodeType, "fegaussianblur") == YES) {
|
||||
return IJSVGNodeTypeFilterEffect;
|
||||
}
|
||||
return IJSVGNodeTypeUnknown;
|
||||
}
|
||||
|
||||
+ (IJSVGBitFlags*)computedAllowedAttributes
|
||||
{
|
||||
static NSMutableDictionary<Class, IJSVGBitFlags*>* computed = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
computed = [[NSMutableDictionary alloc] init];
|
||||
});
|
||||
|
||||
@synchronized (computed) {
|
||||
IJSVGBitFlags* set = computed[self];
|
||||
if(set == nil) {
|
||||
set = [self allowedAttributes];
|
||||
computed[(id<NSCopying>)self] = set;
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
+ (IJSVGBitFlags*)allowedAttributes
|
||||
{
|
||||
IJSVGBitFlags64* storage = [[IJSVGBitFlags64 alloc] init];
|
||||
[storage setBit:IJSVGNodeAttributeStyle];
|
||||
[storage setBit:IJSVGNodeAttributeClass];
|
||||
[storage setBit:IJSVGNodeAttributeTransform];
|
||||
[storage setBit:IJSVGNodeAttributeID];
|
||||
[storage setBit:IJSVGNodeAttributeDisplay];
|
||||
return storage;
|
||||
}
|
||||
|
||||
+ (BOOL)typeIsPathable:(IJSVGNodeType)type
|
||||
{
|
||||
return type == IJSVGNodeTypePath || type == IJSVGNodeTypeRect ||
|
||||
type == IJSVGNodeTypeCircle || type == IJSVGNodeTypeEllipse ||
|
||||
type == IJSVGNodeTypePolygon || type == IJSVGNodeTypePolyline ||
|
||||
type == IJSVGNodeTypeLine;
|
||||
}
|
||||
|
||||
+ (void)walkNodeTree:(IJSVGNode*)node
|
||||
handler:(IJSVGNodeWalkHandler)handler
|
||||
{
|
||||
@@ -183,13 +208,80 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSArray<IJSVGNode*>*)node:(IJSVGNode*)node
|
||||
nodesMatchingTraits:(IJSVGNodeTraits)traits
|
||||
{
|
||||
NSMutableArray<IJSVGNode*>* nodes = [[NSMutableArray alloc] init];
|
||||
IJSVGNodeWalkHandler handler = ^(IJSVGNode* node,
|
||||
BOOL* allowChildNodes,
|
||||
BOOL* stop) {
|
||||
// dont compute nodes that are not designed
|
||||
// to be rendered
|
||||
if(node.shouldRender == NO) {
|
||||
*allowChildNodes = NO;
|
||||
return;
|
||||
}
|
||||
|
||||
if([node matchesTraits:traits] == YES) {
|
||||
[nodes addObject:node];
|
||||
}
|
||||
};
|
||||
[IJSVGNode walkNodeTree:node
|
||||
handler:handler];
|
||||
return nodes;
|
||||
}
|
||||
|
||||
+ (BOOL)node:(IJSVGNode*)node
|
||||
containsNodesMatchingTraits:(IJSVGNodeTraits)traits
|
||||
{
|
||||
__block IJSVGNodeTraits matchedTraits = IJSVGNodeTraitNone;
|
||||
IJSVGNodeWalkHandler handler = ^(IJSVGNode* node,
|
||||
BOOL* allowChildNodes,
|
||||
BOOL* stop) {
|
||||
// dont compute nodes that are not designed
|
||||
// to be rendered
|
||||
if(node.shouldRender == NO) {
|
||||
*allowChildNodes = NO;
|
||||
return;
|
||||
}
|
||||
|
||||
// check for stroke
|
||||
if((traits & IJSVGNodeTraitStroked) == IJSVGNodeTraitStroked &&
|
||||
[node matchesTraits:IJSVGNodeTraitStroked] == YES) {
|
||||
matchedTraits |= IJSVGNodeTraitStroked;
|
||||
}
|
||||
|
||||
// check for pathed
|
||||
if((traits & IJSVGNodeTraitPathed) == IJSVGNodeTraitPathed &&
|
||||
[node matchesTraits:IJSVGNodeTraitPathed] == YES) {
|
||||
matchedTraits |= IJSVGNodeTraitPathed;
|
||||
}
|
||||
|
||||
// check for paintable
|
||||
if((traits & IJSVGNodeTraitPaintable) == IJSVGNodeTraitPaintable &&
|
||||
[node matchesTraits:IJSVGNodeTraitPaintable] == YES) {
|
||||
matchedTraits |= IJSVGNodeTraitPaintable;
|
||||
}
|
||||
|
||||
// simply check if masks equal, if they are, stop this loop
|
||||
// and return the evaluation
|
||||
if(matchedTraits == traits) {
|
||||
*stop = YES;
|
||||
}
|
||||
};
|
||||
[IJSVGNode walkNodeTree:node
|
||||
handler:handler];
|
||||
return matchedTraits == traits;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
if((self = [super init]) != nil) {
|
||||
self.opacity = [IJSVGUnitLength unitWithFloat:1.f];
|
||||
self.fillOpacity = [IJSVGUnitLength unitWithFloat:1.f];
|
||||
self.fillOpacity.inherit = YES;
|
||||
|
||||
self.strokeDashArrayCount = IJSVGInheritedIntegerValue;
|
||||
self.strokeDashOffset = [IJSVGUnitLength unitWithFloat:0.f];
|
||||
self.shouldRender = YES;
|
||||
|
||||
@@ -200,6 +292,7 @@
|
||||
self.strokeWidth.inherit = YES;
|
||||
|
||||
self.windingRule = IJSVGWindingRuleInherit;
|
||||
self.clipRule = IJSVGWindingRuleInherit;
|
||||
self.lineCapStyle = IJSVGLineCapStyleInherit;
|
||||
self.lineJoinStyle = IJSVGLineJoinStyleInherit;
|
||||
self.units = IJSVGUnitInherit;
|
||||
@@ -207,6 +300,9 @@
|
||||
|
||||
self.blendMode = IJSVGBlendModeNormal;
|
||||
self.overflowVisibility = IJSVGOverflowVisibilityVisible;
|
||||
|
||||
// peform basic init
|
||||
[self setDefaults];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -243,11 +339,13 @@
|
||||
self.strokeWidth = node.strokeWidth;
|
||||
self.fillOpacity = node.fillOpacity;
|
||||
self.strokeOpacity = node.strokeOpacity;
|
||||
self.strokeMiterLimit = node.strokeMiterLimit;
|
||||
|
||||
self.identifier = node.identifier;
|
||||
|
||||
self.transforms = node.transforms;
|
||||
self.windingRule = node.windingRule;
|
||||
self.clipRule = node.clipRule;
|
||||
self.lineCapStyle = node.lineCapStyle;
|
||||
self.lineJoinStyle = node.lineJoinStyle;
|
||||
self.parentNode = node.parentNode;
|
||||
@@ -271,33 +369,43 @@
|
||||
return node;
|
||||
}
|
||||
|
||||
- (void)postProcess
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setFill:(IJSVGNode*)fill
|
||||
{
|
||||
NSAssert([fill matchesTraits:IJSVGNodeTraitPaintable] || fill == nil, @"Fill must a paintable node.");
|
||||
(void)[_fill release], _fill = nil;
|
||||
_fill = [fill retain];
|
||||
_fill = fill;
|
||||
}
|
||||
|
||||
- (void)setStroke:(IJSVGNode*)stroke
|
||||
{
|
||||
NSAssert([stroke matchesTraits:IJSVGNodeTraitPaintable]|| stroke == nil, @"Stroke must be a paintable node.");
|
||||
(void)[_stroke release], _stroke = nil;
|
||||
_stroke = [stroke retain];
|
||||
_stroke = stroke;
|
||||
}
|
||||
|
||||
// winding rule can inherit..
|
||||
- (IJSVGWindingRule)windingRule
|
||||
{
|
||||
if (_windingRule == IJSVGWindingRuleInherit && _parentNode != nil) {
|
||||
if(_windingRule == IJSVGWindingRuleInherit && _parentNode != nil) {
|
||||
return _parentNode.windingRule;
|
||||
}
|
||||
return _windingRule;
|
||||
}
|
||||
|
||||
- (IJSVGWindingRule)clipRule
|
||||
{
|
||||
if(_clipRule == IJSVGWindingRuleInherit && _parentNode != nil) {
|
||||
return _parentNode.clipRule;
|
||||
}
|
||||
return _clipRule;
|
||||
}
|
||||
|
||||
- (IJSVGLineCapStyle)lineCapStyle
|
||||
{
|
||||
if (_lineCapStyle == IJSVGLineCapStyleInherit) {
|
||||
if (_parentNode != nil) {
|
||||
if(_lineCapStyle == IJSVGLineCapStyleInherit) {
|
||||
if(_parentNode != nil) {
|
||||
return _parentNode.lineCapStyle;
|
||||
}
|
||||
}
|
||||
@@ -306,8 +414,8 @@
|
||||
|
||||
- (IJSVGLineJoinStyle)lineJoinStyle
|
||||
{
|
||||
if (_lineJoinStyle == IJSVGLineJoinStyleInherit) {
|
||||
if (_parentNode != nil) {
|
||||
if(_lineJoinStyle == IJSVGLineJoinStyleInherit) {
|
||||
if(_parentNode != nil) {
|
||||
return _parentNode.lineJoinStyle;
|
||||
}
|
||||
}
|
||||
@@ -318,7 +426,7 @@
|
||||
// if they dont exist on this specific node
|
||||
- (IJSVGUnitLength*)opacity
|
||||
{
|
||||
if (_opacity.inherit && _parentNode != nil) {
|
||||
if(_opacity.inherit && _parentNode != nil) {
|
||||
return _parentNode.opacity;
|
||||
}
|
||||
return _opacity;
|
||||
@@ -328,7 +436,7 @@
|
||||
// if they dont exist on this specific node
|
||||
- (IJSVGUnitLength*)fillOpacity
|
||||
{
|
||||
if (_fillOpacity.inherit && _parentNode != nil) {
|
||||
if(_fillOpacity.inherit && _parentNode != nil) {
|
||||
return _parentNode.fillOpacity;
|
||||
}
|
||||
return _fillOpacity;
|
||||
@@ -338,7 +446,7 @@
|
||||
// if they dont exist on this specific node
|
||||
- (IJSVGUnitLength*)strokeWidth
|
||||
{
|
||||
if (_strokeWidth.inherit && _parentNode != nil) {
|
||||
if(_strokeWidth.inherit && _parentNode != nil) {
|
||||
return _parentNode.strokeWidth;
|
||||
}
|
||||
return _strokeWidth;
|
||||
@@ -346,7 +454,7 @@
|
||||
|
||||
- (NSArray<NSNumber*>*)lineDashPattern
|
||||
{
|
||||
NSMutableArray* arr = [[[NSMutableArray alloc] initWithCapacity:self.strokeDashArrayCount] autorelease];
|
||||
NSMutableArray* arr = [[NSMutableArray alloc] initWithCapacity:self.strokeDashArrayCount];
|
||||
for (NSInteger i = 0; i < self.strokeDashArrayCount; i++) {
|
||||
[arr addObject:@((CGFloat)self.strokeDashArray[i])];
|
||||
}
|
||||
@@ -357,15 +465,39 @@
|
||||
// if they dont exist on this specific node
|
||||
- (IJSVGNode*)stroke
|
||||
{
|
||||
if (_stroke == nil && _parentNode != nil) {
|
||||
if(_stroke == nil && _parentNode != nil) {
|
||||
return _parentNode.stroke;
|
||||
}
|
||||
return _stroke;
|
||||
}
|
||||
|
||||
- (CGFloat*)strokeDashArray
|
||||
{
|
||||
if(_strokeDashArray == NULL && _parentNode != nil) {
|
||||
return _parentNode.strokeDashArray;
|
||||
}
|
||||
return _strokeDashArray;
|
||||
}
|
||||
|
||||
- (NSInteger)strokeDashArrayCount
|
||||
{
|
||||
if(_strokeDashArrayCount == IJSVGInheritedIntegerValue && _parentNode != nil) {
|
||||
return _parentNode.strokeDashArrayCount;
|
||||
}
|
||||
return _strokeDashArrayCount;
|
||||
}
|
||||
|
||||
- (IJSVGUnitLength *)strokeDashOffset
|
||||
{
|
||||
if(_strokeDashOffset == nil && _parentNode != nil) {
|
||||
return _parentNode.strokeDashOffset;
|
||||
}
|
||||
return _strokeDashOffset;
|
||||
}
|
||||
|
||||
- (IJSVGUnitLength*)strokeOpacity
|
||||
{
|
||||
if (_strokeOpacity.inherit && _parentNode != nil) {
|
||||
if(_strokeOpacity.inherit && _parentNode != nil) {
|
||||
return _parentNode.strokeOpacity;
|
||||
}
|
||||
return _strokeOpacity;
|
||||
@@ -375,7 +507,7 @@
|
||||
// must be on the path, it can also be on the
|
||||
- (IJSVGNode*)fill
|
||||
{
|
||||
if (_fill == nil && _parentNode != nil) {
|
||||
if(_fill == nil && _parentNode != nil) {
|
||||
return _parentNode.fill;
|
||||
}
|
||||
return _fill;
|
||||
@@ -397,6 +529,14 @@
|
||||
return _contentUnits;
|
||||
}
|
||||
|
||||
- (IJSVGUnitLength*)strokeMiterLimit
|
||||
{
|
||||
if(_strokeMiterLimit == nil && _parentNode != nil) {
|
||||
return _parentNode.strokeMiterLimit;
|
||||
}
|
||||
return _strokeMiterLimit;
|
||||
}
|
||||
|
||||
- (IJSVGUnitType)contentUnitsWithReferencingNodeBounds:(CGRect*)bounds
|
||||
{
|
||||
IJSVGNode* node = nil;
|
||||
@@ -414,6 +554,15 @@
|
||||
return _contentUnits;
|
||||
}
|
||||
|
||||
- (IJSVGNodeTraits)traits
|
||||
{
|
||||
if(_computedTraits == NO) {
|
||||
_computedTraits = YES;
|
||||
[self computeTraits];
|
||||
}
|
||||
return _traits;
|
||||
}
|
||||
|
||||
- (void)addTraits:(IJSVGNodeTraits)traits
|
||||
{
|
||||
_traits |= traits;
|
||||
@@ -426,7 +575,7 @@
|
||||
|
||||
- (BOOL)matchesTraits:(IJSVGNodeTraits)traits
|
||||
{
|
||||
return (_traits & traits) == traits;
|
||||
return (self.traits & traits) == traits;
|
||||
}
|
||||
|
||||
- (void)computeTraits
|
||||
@@ -434,6 +583,10 @@
|
||||
// by default this does nothing
|
||||
}
|
||||
|
||||
- (void)setDefaults
|
||||
{
|
||||
}
|
||||
|
||||
- (instancetype)detach
|
||||
{
|
||||
self.parentNode = nil;
|
||||
@@ -442,7 +595,68 @@
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ %@ %@",self.name,self.classNameList,self.identifier];
|
||||
return [NSString stringWithFormat:@"%@ %@ %@ %@",NSStringFromClass(self.class),
|
||||
self.name,self.classNameList,self.identifier];
|
||||
}
|
||||
|
||||
- (BOOL)detachedFromParentNode
|
||||
{
|
||||
return self.type == IJSVGNodeTypeClipPath ||
|
||||
self.type == IJSVGNodeTypeMask;
|
||||
}
|
||||
|
||||
- (IJSVGRootNode*)rootNode
|
||||
{
|
||||
IJSVGNode* parent = self;
|
||||
while([parent isKindOfClass:IJSVGRootNode.class] == NO) {
|
||||
parent = parent.parentNode;
|
||||
if(parent == nil) {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
return (IJSVGRootNode*)parent;
|
||||
}
|
||||
|
||||
- (NSSet<IJSVGNode*>*)nodesMatchingTypes:(NSIndexSet*)types
|
||||
{
|
||||
NSMutableSet<IJSVGNode*>* nodes = [[NSMutableSet alloc] init];
|
||||
IJSVGNodeWalkHandler handler = ^(IJSVGNode* node,
|
||||
BOOL* allowChildNodes,
|
||||
BOOL* stop) {
|
||||
if([types containsIndex:node.type] == YES) {
|
||||
[nodes addObject:node];
|
||||
}
|
||||
};
|
||||
[self.class walkNodeTree:self
|
||||
handler:handler];
|
||||
return nodes.copy;
|
||||
}
|
||||
|
||||
- (instancetype)parentNodeMatchingClass:(Class)class
|
||||
{
|
||||
IJSVGNode* parent = self.parentNode;
|
||||
if([parent isKindOfClass:class] == YES) {
|
||||
return parent;
|
||||
}
|
||||
return [parent parentNodeMatchingClass:class];
|
||||
}
|
||||
|
||||
- (instancetype)rootNodeMatchingClass:(Class)class
|
||||
{
|
||||
IJSVGRootNode* rootNode = self.rootNode;
|
||||
IJSVGNode* parentNode = self.parentNode;
|
||||
IJSVGNode* foundNode = nil;
|
||||
while(parentNode != nil) {
|
||||
// break on root node or if its matching
|
||||
if(parentNode == rootNode || parentNode == nil) {
|
||||
break;
|
||||
}
|
||||
if([parentNode isKindOfClass:class] == YES) {
|
||||
foundNode = parentNode;
|
||||
}
|
||||
parentNode = parentNode.parentNode;
|
||||
}
|
||||
return foundNode;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -31,6 +31,10 @@ typedef NS_ENUM(NSInteger, IJSVGPrimitivePathType) {
|
||||
@property (nonatomic, readonly) CGRect controlPointBoundingBox;
|
||||
@property (nonatomic, readonly) CGRect pathBoundingBox;
|
||||
|
||||
+ (void)recursivelyAddPathedNodesPaths:(NSArray<IJSVGNode*>*)nodes
|
||||
transform:(CGAffineTransform)transform
|
||||
toPath:(CGMutablePathRef)mutPath;
|
||||
|
||||
- (void)close;
|
||||
- (NSPoint)currentPoint;
|
||||
|
||||
|
||||
@@ -7,26 +7,75 @@
|
||||
//
|
||||
|
||||
#import <IJSVG/IJSVGPath.h>
|
||||
#import <IJSVG/IJSVGGroup.h>
|
||||
|
||||
@implementation IJSVGPath
|
||||
|
||||
+ (IJSVGBitFlags*)allowedAttributes
|
||||
{
|
||||
IJSVGBitFlags64* storage = [[IJSVGBitFlags64 alloc] init];
|
||||
[storage addBits:[super allowedAttributes]];
|
||||
[storage setBit:IJSVGNodeAttributeFill];
|
||||
[storage setBit:IJSVGNodeAttributeFillOpacity];
|
||||
[storage setBit:IJSVGNodeAttributeFillRule];
|
||||
[storage setBit:IJSVGNodeAttributeX];
|
||||
[storage setBit:IJSVGNodeAttributeY];
|
||||
[storage setBit:IJSVGNodeAttributeStroke];
|
||||
[storage setBit:IJSVGNodeAttributeStrokeWidth];
|
||||
[storage setBit:IJSVGNodeAttributeStrokeOpacity];
|
||||
[storage setBit:IJSVGNodeAttributeStrokeLineCap];
|
||||
[storage setBit:IJSVGNodeAttributeStrokeLineJoin];
|
||||
[storage setBit:IJSVGNodeAttributeStrokeDashArray];
|
||||
[storage setBit:IJSVGNodeAttributeStrokeDashOffset];
|
||||
[storage setBit:IJSVGNodeAttributeClipPath];
|
||||
[storage setBit:IJSVGNodeAttributeMask];
|
||||
[storage setBit:IJSVGNodeAttributeOpacity];
|
||||
[storage setBit:IJSVGNodeAttributeBlendMode];
|
||||
return storage;
|
||||
}
|
||||
|
||||
+ (void)recursivelyAddPathedNodesPaths:(NSArray<IJSVGNode*>*)nodes
|
||||
transform:(CGAffineTransform)transform
|
||||
toPath:(CGMutablePathRef)mutPath
|
||||
{
|
||||
for(IJSVGPath* pathNode in nodes) {
|
||||
// just a pathed node
|
||||
if([pathNode matchesTraits:IJSVGNodeTraitPathed] == YES) {
|
||||
CGPathAddPath(mutPath, &transform, pathNode.path);
|
||||
continue;
|
||||
}
|
||||
|
||||
// could be a use group
|
||||
if([pathNode isKindOfClass:IJSVGGroup.class] == YES) {
|
||||
IJSVGGroup* useGroup = (IJSVGGroup*)pathNode;
|
||||
[self recursivelyAddPathedNodesPaths:useGroup.children
|
||||
transform:transform
|
||||
toPath:mutPath];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if(_path != NULL) {
|
||||
(void)CGPathRelease(_path), _path = NULL;
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]) != nil) {
|
||||
if((self = [super init]) != nil) {
|
||||
_primitiveType = kIJSVGPrimitivePathTypePath;
|
||||
_path = CGPathCreateMutable();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setDefaults
|
||||
{
|
||||
[self addTraits:IJSVGNodeTraitPathed];
|
||||
}
|
||||
|
||||
- (CGRect)bounds
|
||||
{
|
||||
return self.pathBoundingBox;
|
||||
@@ -51,12 +100,12 @@
|
||||
|
||||
- (CGRect)pathBoundingBox
|
||||
{
|
||||
return CGPathGetPathBoundingBox(_path);
|
||||
return CGPathGetBoundingBox(_path);
|
||||
}
|
||||
|
||||
- (CGRect)controlPointBoundingBox
|
||||
{
|
||||
return CGPathGetBoundingBox(_path);
|
||||
return CGPathGetPathBoundingBox(_path);
|
||||
}
|
||||
|
||||
- (NSPoint)currentPoint
|
||||
@@ -81,7 +130,8 @@
|
||||
// component to then remove the trait if its 0.f
|
||||
if([self.stroke isKindOfClass:IJSVGColorNode.class] == YES) {
|
||||
IJSVGColorNode* strokeColor = (IJSVGColorNode*)self.stroke;
|
||||
if(strokeColor.color.alphaComponent == 0.f) {
|
||||
if(strokeColor.color.alphaComponent == 0.f ||
|
||||
strokeColor.isNoneOrTransparent == YES) {
|
||||
[self removeTraits:IJSVGNodeTraitStroked];
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user