Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f84aa9070 | |||
| 200fd6893d | |||
| 01ad4eaeb2 | |||
| 6b1c988d89 | |||
| c91ac95bc2 | |||
| cf14f27560 | |||
| cef1de35d7 | |||
| c1a98ef5a6 | |||
| 690e1c8619 | |||
| eda2b73eb2 | |||
| f00ede11f0 | |||
| 169da55131 | |||
| acfec29765 | |||
| a44cc7c098 | |||
| 171e97451b | |||
| 27e096350e | |||
| 04646fe4ec | |||
| a092b612a8 | |||
| d176fe6396 | |||
| c94de1d241 | |||
| 1294372daa | |||
| 60e5c6b68a | |||
| 06c8191732 | |||
| 2f0bead7a4 | |||
| ee46609165 | |||
| 9e58ae6e19 | |||
| 199d1a5707 | |||
| f72ae8b401 | |||
| c126f511d6 |
@@ -8,6 +8,8 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
343A19181FB2212C000652A2 /* IJSVGGradientUnitLength.m in Sources */ = {isa = PBXBuildFile; fileRef = 343A19171FB2212C000652A2 /* IJSVGGradientUnitLength.m */; };
|
||||
59069A2922D0ED85004DDEA5 /* compuserver_msn_Ford_Focus.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59069A2822D0ED85004DDEA5 /* compuserver_msn_Ford_Focus.svg */; };
|
||||
59069A2B22D0EE0E004DDEA5 /* test (1).svg in Resources */ = {isa = PBXBuildFile; fileRef = 59069A2A22D0EE0E004DDEA5 /* test (1).svg */; };
|
||||
590C87EB201F9888004A1554 /* json.svg in Resources */ = {isa = PBXBuildFile; fileRef = 590C87EA201F9888004A1554 /* json.svg */; };
|
||||
590C87ED201FA08C004A1554 /* intertwingly.svg in Resources */ = {isa = PBXBuildFile; fileRef = 590C87EC201FA08C004A1554 /* intertwingly.svg */; };
|
||||
590C87EF201FA093004A1554 /* NewTux.svg in Resources */ = {isa = PBXBuildFile; fileRef = 590C87EE201FA092004A1554 /* NewTux.svg */; };
|
||||
@@ -35,6 +37,7 @@
|
||||
595665DE19B6309C00D805FF /* test.svg in Resources */ = {isa = PBXBuildFile; fileRef = 595665DD19B6309C00D805FF /* test.svg */; };
|
||||
595665E119B630B600D805FF /* SVGView.m in Sources */ = {isa = PBXBuildFile; fileRef = 595665E019B630B600D805FF /* SVGView.m */; };
|
||||
597046A21E24352700A60138 /* IJSVGStrokeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 597046A11E24352700A60138 /* IJSVGStrokeLayer.m */; };
|
||||
597AC83322CFD0FC007C0E42 /* home.svg in Resources */ = {isa = PBXBuildFile; fileRef = 597AC83222CFD0FC007C0E42 /* home.svg */; };
|
||||
5986308719BA104800CF15EA /* linecap.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5986308619BA104800CF15EA /* linecap.svg */; };
|
||||
5986308A19BA106D00CF15EA /* SVGExampleView5.m in Sources */ = {isa = PBXBuildFile; fileRef = 5986308919BA106D00CF15EA /* SVGExampleView5.m */; };
|
||||
5986308C19BA180E00CF15EA /* dashed.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5986308B19BA180E00CF15EA /* dashed.svg */; };
|
||||
@@ -51,11 +54,7 @@
|
||||
59A3DA6D1E283022003E59A9 /* IJSVGTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A3DA6C1E283022003E59A9 /* IJSVGTransaction.m */; };
|
||||
59B93C6D19B7D1840063E823 /* paperplane.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59B93C6C19B7D1840063E823 /* paperplane.svg */; };
|
||||
59B93C6F19B7D32C0063E823 /* products.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59B93C6E19B7D32C0063E823 /* products.svg */; };
|
||||
59D1E39E2022577500C54672 /* IJSVGQuartzRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59D1E39D2022577500C54672 /* IJSVGQuartzRenderer.m */; };
|
||||
59D1E3A0202279CA00C54672 /* Group.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59D1E39F202279CA00C54672 /* Group.svg */; };
|
||||
59D6C4142049939800F16F13 /* move.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59D6C4132049939800F16F13 /* move.svg */; };
|
||||
59D6C4162049947E00F16F13 /* sprite-1.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59D6C4152049947E00F16F13 /* sprite-1.svg */; };
|
||||
59D6C4182049977E00F16F13 /* fa-brands.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59D6C4172049977E00F16F13 /* fa-brands.svg */; };
|
||||
59E0F5ED1E29964700F757F7 /* IJSVGUnitLength.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E0F5EC1E29964700F757F7 /* IJSVGUnitLength.m */; };
|
||||
59E2645119BA240D008A6FDB /* IJSVG.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2641C19BA240D008A6FDB /* IJSVG.m */; };
|
||||
59E2645219BA240D008A6FDB /* IJSVGBezierPathAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E2641E19BA240D008A6FDB /* IJSVGBezierPathAdditions.m */; };
|
||||
@@ -90,6 +89,10 @@
|
||||
59E8ABF31E2167D90032A80C /* IJSVGImageLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E8ABF21E2167D90032A80C /* IJSVGImageLayer.m */; };
|
||||
59E8ABF61E2176340032A80C /* IJSVGGroupLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E8ABF51E2176340032A80C /* IJSVGGroupLayer.m */; };
|
||||
59E8ABF91E219C860032A80C /* IJSVGMath.m in Sources */ = {isa = PBXBuildFile; fileRef = 59E8ABF81E219C860032A80C /* IJSVGMath.m */; };
|
||||
59EA311622CF395400DAB3B7 /* IJSVGStringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EA310F22CF395400DAB3B7 /* IJSVGStringAdditions.m */; };
|
||||
59EA311722CF395400DAB3B7 /* IJSVGRendering.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EA311022CF395400DAB3B7 /* IJSVGRendering.m */; };
|
||||
59EA311822CF395400DAB3B7 /* IJSVGImageRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EA311322CF395400DAB3B7 /* IJSVGImageRep.m */; };
|
||||
59EA311922CF395400DAB3B7 /* IJSVGView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EA311422CF395400DAB3B7 /* IJSVGView.m */; };
|
||||
59F799E219B880CE00096CB7 /* htc_one.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59F799E119B880CE00096CB7 /* htc_one.svg */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -106,6 +109,8 @@
|
||||
/* Begin PBXFileReference section */
|
||||
343A19161FB2212C000652A2 /* IJSVGGradientUnitLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGradientUnitLength.h; sourceTree = "<group>"; };
|
||||
343A19171FB2212C000652A2 /* IJSVGGradientUnitLength.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGradientUnitLength.m; sourceTree = "<group>"; };
|
||||
59069A2822D0ED85004DDEA5 /* compuserver_msn_Ford_Focus.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = compuserver_msn_Ford_Focus.svg; sourceTree = "<group>"; };
|
||||
59069A2A22D0EE0E004DDEA5 /* test (1).svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "test (1).svg"; sourceTree = "<group>"; };
|
||||
590C87EA201F9888004A1554 /* json.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = json.svg; sourceTree = "<group>"; };
|
||||
590C87EC201FA08C004A1554 /* intertwingly.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = intertwingly.svg; sourceTree = "<group>"; };
|
||||
590C87EE201FA092004A1554 /* NewTux.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = NewTux.svg; sourceTree = "<group>"; };
|
||||
@@ -152,6 +157,7 @@
|
||||
595665E019B630B600D805FF /* SVGView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGView.m; sourceTree = "<group>"; };
|
||||
597046A01E24352700A60138 /* IJSVGStrokeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStrokeLayer.h; sourceTree = "<group>"; };
|
||||
597046A11E24352700A60138 /* IJSVGStrokeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStrokeLayer.m; sourceTree = "<group>"; };
|
||||
597AC83222CFD0FC007C0E42 /* home.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = home.svg; sourceTree = "<group>"; };
|
||||
5986308619BA104800CF15EA /* linecap.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = linecap.svg; sourceTree = "<group>"; };
|
||||
5986308819BA106D00CF15EA /* SVGExampleView5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGExampleView5.h; sourceTree = "<group>"; };
|
||||
5986308919BA106D00CF15EA /* SVGExampleView5.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGExampleView5.m; sourceTree = "<group>"; };
|
||||
@@ -178,12 +184,7 @@
|
||||
59A3DA6C1E283022003E59A9 /* IJSVGTransaction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGTransaction.m; sourceTree = "<group>"; };
|
||||
59B93C6C19B7D1840063E823 /* paperplane.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = paperplane.svg; sourceTree = "<group>"; };
|
||||
59B93C6E19B7D32C0063E823 /* products.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = products.svg; sourceTree = "<group>"; };
|
||||
59D1E39C2022577500C54672 /* IJSVGQuartzRenderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IJSVGQuartzRenderer.h; sourceTree = "<group>"; };
|
||||
59D1E39D2022577500C54672 /* IJSVGQuartzRenderer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IJSVGQuartzRenderer.m; sourceTree = "<group>"; };
|
||||
59D1E39F202279CA00C54672 /* Group.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Group.svg; sourceTree = "<group>"; };
|
||||
59D6C4132049939800F16F13 /* move.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = move.svg; sourceTree = "<group>"; };
|
||||
59D6C4152049947E00F16F13 /* sprite-1.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "sprite-1.svg"; sourceTree = "<group>"; };
|
||||
59D6C4172049977E00F16F13 /* fa-brands.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "fa-brands.svg"; sourceTree = "<group>"; };
|
||||
59E0F5EB1E29964700F757F7 /* IJSVGUnitLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGUnitLength.h; sourceTree = "<group>"; };
|
||||
59E0F5EC1E29964700F757F7 /* IJSVGUnitLength.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGUnitLength.m; sourceTree = "<group>"; };
|
||||
59E2641B19BA240D008A6FDB /* IJSVG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVG.h; sourceTree = "<group>"; };
|
||||
@@ -252,6 +253,14 @@
|
||||
59E8ABF51E2176340032A80C /* IJSVGGroupLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGroupLayer.m; sourceTree = "<group>"; };
|
||||
59E8ABF71E219C860032A80C /* IJSVGMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGMath.h; sourceTree = "<group>"; };
|
||||
59E8ABF81E219C860032A80C /* IJSVGMath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGMath.m; sourceTree = "<group>"; };
|
||||
59EA310E22CF395300DAB3B7 /* IJSVGImageRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGImageRep.h; sourceTree = "<group>"; };
|
||||
59EA310F22CF395400DAB3B7 /* IJSVGStringAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStringAdditions.m; sourceTree = "<group>"; };
|
||||
59EA311022CF395400DAB3B7 /* IJSVGRendering.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGRendering.m; sourceTree = "<group>"; };
|
||||
59EA311122CF395400DAB3B7 /* IJSVGRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGRendering.h; sourceTree = "<group>"; };
|
||||
59EA311222CF395400DAB3B7 /* IJSVGView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGView.h; sourceTree = "<group>"; };
|
||||
59EA311322CF395400DAB3B7 /* IJSVGImageRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGImageRep.m; sourceTree = "<group>"; };
|
||||
59EA311422CF395400DAB3B7 /* IJSVGView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGView.m; sourceTree = "<group>"; };
|
||||
59EA311522CF395400DAB3B7 /* IJSVGStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStringAdditions.h; sourceTree = "<group>"; };
|
||||
59F799E119B880CE00096CB7 /* htc_one.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = htc_one.svg; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -321,13 +330,14 @@
|
||||
5956657A19B62F4600D805FF /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
59D6C4172049977E00F16F13 /* fa-brands.svg */,
|
||||
59069A2A22D0EE0E004DDEA5 /* test (1).svg */,
|
||||
59069A2822D0ED85004DDEA5 /* compuserver_msn_Ford_Focus.svg */,
|
||||
597AC83222CFD0FC007C0E42 /* home.svg */,
|
||||
59D1E39F202279CA00C54672 /* Group.svg */,
|
||||
590C87F5201FD0D4004A1554 /* car.svg */,
|
||||
590C87F3201FC9E3004A1554 /* radialgradient2.svg */,
|
||||
590C87F0201FBF27004A1554 /* AJ_Digital_Camera.svg */,
|
||||
590C87EC201FA08C004A1554 /* intertwingly.svg */,
|
||||
59D6C4152049947E00F16F13 /* sprite-1.svg */,
|
||||
590C87EE201FA092004A1554 /* NewTux.svg */,
|
||||
590C87EA201F9888004A1554 /* json.svg */,
|
||||
5991A2AA201E310200913E3B /* heart.svg */,
|
||||
@@ -340,7 +350,6 @@
|
||||
595665DD19B6309C00D805FF /* test.svg */,
|
||||
5986308619BA104800CF15EA /* linecap.svg */,
|
||||
5986308B19BA180E00CF15EA /* dashed.svg */,
|
||||
59D6C4132049939800F16F13 /* move.svg */,
|
||||
5956657B19B62F4600D805FF /* Info.plist */,
|
||||
5956657C19B62F4600D805FF /* main.m */,
|
||||
5956659A19B62F9500D805FF /* IJSVGExample-Prefix.pch */,
|
||||
@@ -377,6 +386,14 @@
|
||||
59E2641A19BA240D008A6FDB /* source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
59EA310E22CF395300DAB3B7 /* IJSVGImageRep.h */,
|
||||
59EA311322CF395400DAB3B7 /* IJSVGImageRep.m */,
|
||||
59EA311122CF395400DAB3B7 /* IJSVGRendering.h */,
|
||||
59EA311022CF395400DAB3B7 /* IJSVGRendering.m */,
|
||||
59EA311522CF395400DAB3B7 /* IJSVGStringAdditions.h */,
|
||||
59EA310F22CF395400DAB3B7 /* IJSVGStringAdditions.m */,
|
||||
59EA311222CF395400DAB3B7 /* IJSVGView.h */,
|
||||
59EA311422CF395400DAB3B7 /* IJSVGView.m */,
|
||||
59A3DA6B1E283022003E59A9 /* IJSVGTransaction.h */,
|
||||
59A3DA6C1E283022003E59A9 /* IJSVGTransaction.m */,
|
||||
598759F41E242C850024CC3F /* IJSVGExporterPathInstruction.h */,
|
||||
@@ -478,8 +495,6 @@
|
||||
597046A11E24352700A60138 /* IJSVGStrokeLayer.m */,
|
||||
59E0F5EB1E29964700F757F7 /* IJSVGUnitLength.h */,
|
||||
59E0F5EC1E29964700F757F7 /* IJSVGUnitLength.m */,
|
||||
59D1E39C2022577500C54672 /* IJSVGQuartzRenderer.h */,
|
||||
59D1E39D2022577500C54672 /* IJSVGQuartzRenderer.m */,
|
||||
);
|
||||
name = source;
|
||||
path = ../../source;
|
||||
@@ -546,6 +561,7 @@
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
@@ -568,23 +584,23 @@
|
||||
59B93C6D19B7D1840063E823 /* paperplane.svg in Resources */,
|
||||
5956658219B62F4600D805FF /* Images.xcassets in Resources */,
|
||||
590C87ED201FA08C004A1554 /* intertwingly.svg in Resources */,
|
||||
59D6C4182049977E00F16F13 /* fa-brands.svg in Resources */,
|
||||
590C87F1201FBF27004A1554 /* AJ_Digital_Camera.svg in Resources */,
|
||||
59069A2B22D0EE0E004DDEA5 /* test (1).svg in Resources */,
|
||||
590C87EF201FA093004A1554 /* NewTux.svg in Resources */,
|
||||
59D6C4162049947E00F16F13 /* sprite-1.svg in Resources */,
|
||||
59265CE81C4F840400F333F0 /* css.svg in Resources */,
|
||||
595665DE19B6309C00D805FF /* test.svg in Resources */,
|
||||
597AC83322CFD0FC007C0E42 /* home.svg in Resources */,
|
||||
590C87EB201F9888004A1554 /* json.svg in Resources */,
|
||||
59D1E3A0202279CA00C54672 /* Group.svg in Resources */,
|
||||
59F799E219B880CE00096CB7 /* htc_one.svg in Resources */,
|
||||
59B93C6F19B7D32C0063E823 /* products.svg in Resources */,
|
||||
5991A2A9201E30E600913E3B /* gradients.svg in Resources */,
|
||||
59069A2922D0ED85004DDEA5 /* compuserver_msn_Ford_Focus.svg in Resources */,
|
||||
5986308719BA104800CF15EA /* linecap.svg in Resources */,
|
||||
5956658519B62F4600D805FF /* MainMenu.xib in Resources */,
|
||||
590C87F4201FC9E4004A1554 /* radialgradient2.svg in Resources */,
|
||||
59459CEC19B906FE00CE493B /* clipped.svg in Resources */,
|
||||
590C87F6201FD0D4004A1554 /* car.svg in Resources */,
|
||||
59D6C4142049939800F16F13 /* move.svg in Resources */,
|
||||
5991A2AB201E310200913E3B /* heart.svg in Resources */,
|
||||
5986308C19BA180E00CF15EA /* dashed.svg in Resources */,
|
||||
);
|
||||
@@ -608,7 +624,7 @@
|
||||
59E2646919BA240D008A6FDB /* IJSVGStyle.m in Sources */,
|
||||
59E2646419BA240D008A6FDB /* IJSVGLinearGradient.m in Sources */,
|
||||
595665DC19B6302600D805FF /* README.md in Sources */,
|
||||
59D1E39E2022577500C54672 /* IJSVGQuartzRenderer.m in Sources */,
|
||||
59EA311922CF395400DAB3B7 /* IJSVGView.m in Sources */,
|
||||
5941DAFD1CF9BC9B00B3A911 /* IJSVGImage.m in Sources */,
|
||||
599465DE1C4AA87200A2EEF3 /* IJSVGStyleSheetSelector.m in Sources */,
|
||||
5948DED61BB2BFE5004156FF /* IJSVGWriter.m in Sources */,
|
||||
@@ -637,6 +653,7 @@
|
||||
5956658019B62F4600D805FF /* AppDelegate.m in Sources */,
|
||||
59E2646519BA240D008A6FDB /* IJSVGNode.m in Sources */,
|
||||
591A13E11E19838F001D1629 /* IJSVGText.m in Sources */,
|
||||
59EA311822CF395400DAB3B7 /* IJSVGImageRep.m in Sources */,
|
||||
59A11E6C19B89CEA00E44498 /* SVGExampleView1.m in Sources */,
|
||||
59A3DA6D1E283022003E59A9 /* IJSVGTransaction.m in Sources */,
|
||||
59E2646A19BA240D008A6FDB /* IJSVGTransform.m in Sources */,
|
||||
@@ -648,6 +665,7 @@
|
||||
598759F61E242C850024CC3F /* IJSVGExporterPathInstruction.m in Sources */,
|
||||
59E2645E19BA240D008A6FDB /* IJSVGCommandSmoothCurve.m in Sources */,
|
||||
59E2645819BA240D008A6FDB /* IJSVGCommandCommandSmoothQuadraticCurve.m in Sources */,
|
||||
59EA311622CF395400DAB3B7 /* IJSVGStringAdditions.m in Sources */,
|
||||
59E2645D19BA240D008A6FDB /* IJSVGCommandQuadraticCurve.m in Sources */,
|
||||
59E2646719BA240D008A6FDB /* IJSVGPath.m in Sources */,
|
||||
59E8ABED1E211EBE0032A80C /* IJSVGLayer.m in Sources */,
|
||||
@@ -656,6 +674,7 @@
|
||||
59A11E7219B89D6600E44498 /* SVGExampleView3.m in Sources */,
|
||||
59E0F5ED1E29964700F757F7 /* IJSVGUnitLength.m in Sources */,
|
||||
5956657D19B62F4600D805FF /* main.m in Sources */,
|
||||
59EA311722CF395400DAB3B7 /* IJSVGRendering.m in Sources */,
|
||||
59A11E6F19B89D2000E44498 /* SVGExampleView2.m in Sources */,
|
||||
5948DED51BB2BFE5004156FF /* IJSVGFontConverter.m in Sources */,
|
||||
59E2646319BA240D008A6FDB /* IJSVGGroup.m in Sources */,
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
Binary file not shown.
+1
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
uuid = "21141E92-29FD-4CF6-AB04-0D4E4FD9A4AC"
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
</Bucket>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14835.7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14835.7"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -667,17 +667,18 @@
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
<point key="canvasLocation" x="139" y="154"/>
|
||||
</menu>
|
||||
<window title="IJSVGExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<window title="IJSVGExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" appearanceType="aqua" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="600" height="479"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" misplaced="YES" id="EiT-Mj-1SZ">
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="3008" height="1669"/>
|
||||
<view key="contentView" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="479"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<customView misplaced="YES" id="hhC-1S-CCX" customClass="SVGView">
|
||||
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hhC-1S-CCX" customClass="SVGView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="479"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</customView>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
if( ( self = [super initWithFrame:frameRect] ) != nil )
|
||||
{
|
||||
svg = [self svg];
|
||||
svg.renderQuality = IJSVGRenderQualityLow;
|
||||
svg.renderQuality = IJSVGRenderQualityFullResolution;
|
||||
svg.renderingBackingScaleHelper = ^{
|
||||
return self.window.backingScaleFactor;
|
||||
};
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
- (IJSVG *)svg
|
||||
{
|
||||
return [IJSVG svgNamed:@"car"];
|
||||
return [IJSVG svgNamed:@"test (1)"];
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 318 KiB |
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="508" height="508" version="1.1" viewBox="0 0 508 508" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!--Generated by IJSVG (https://github.com/iconjar/IJSVG)-->
|
||||
<defs>
|
||||
<linearGradient id="a" x1="0.145454" x2="0.599999" y1="0.257812" y2="0.570312" gradientTransform="matrix(1,0,0,1,-7.61378e-09,-1.86769e-08)">
|
||||
<stop offset="0%" stop-color="#FBDDB2" stop-opacity="0.99"></stop>
|
||||
<stop offset="100%" stop-color="#EFA81A" stop-opacity="0.95"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" x1="-0.0270271" x2="0.783784" y1="0.46875" y2="0.476562" gradientTransform="matrix(1,0,0,1,3.52391e-08,-2.90476e-08)">
|
||||
<stop offset="0%" stop-color="#787878" stop-opacity="0.99"></stop>
|
||||
<stop offset="100%" stop-color="#FFF" stop-opacity="0.99"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient id="c" x1="0.235289" x2="0.672269" y1="0.265619" y2="0.59375" gradientTransform="matrix(1,0,0,1,1.18803e-07,-1.01189e-08)" xlink:href="#b"></linearGradient>
|
||||
<linearGradient id="d" x1="0.981639" x2="0.146789" y1="0.0312495" y2="0.601562" gradientTransform="matrix(1,0,0,1,-5.18186e-08,1.7497e-08)" xlink:href="#b"></linearGradient>
|
||||
<linearGradient id="e" x1="1.20507" x2="0.102482" y1="0.523438" y2="0.515617" gradientTransform="matrix(1,0,0,1,8.20491e-05,8.70101e-06)" xlink:href="#b"></linearGradient>
|
||||
<radialGradient id="f" fx="-0.0123102%" fy="-0.0135221%" cx="-0.000123102" cy="-0.000135221" r="0.981982" gradientTransform="matrix(0.897766,0,0,1.11388,0.194914,0.125151)" xlink:href="#a"></radialGradient>
|
||||
<linearGradient id="g" x1="0.242009" x2="0.497717" y1="0.382812" y2="0.507812" gradientTransform="matrix(1,0,0,1,5.50934e-10,1.51001e-09)">
|
||||
<stop offset="0%" stop-color="#CA536D" stop-opacity="0.99"></stop>
|
||||
<stop offset="100%" stop-color="#A81837" stop-opacity="0.95"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g transform="scale(1.00011)">
|
||||
<path fill="url(#a)" fill-rule="evenodd" stroke="#580400" stroke-width="11.905" d="M126.604,52.0403h51.3235v120.598h-51.3235Z"></path>
|
||||
<path fill="none" fill-rule="evenodd" stroke="#154850" stroke-linejoin="round" stroke-width="11.905" d="M111.364,481.507c270.797,-1.602 272.4,0 272.4,0l-1.603,-227.534l-134.597,-132.995l-134.598,136.2c-1.603,1.602 1.42109e-14,222.727 -1.602,224.329Z" transform="matrix(1.07519,0,0,1.07519,-12.0839,-29.7941)"></path>
|
||||
<path fill="url(#b)" fill-rule="evenodd" d="M117.773,475.097c59.287,0 59.287,-1.602 59.287,-1.602c0,0 0,-171.451 0,-171.451c0,0 -57.685,-43.264 -57.685,-43.264c-3.205,1.602 -1.602,217.92 -1.602,216.317Z" transform="matrix(1.07519,0,0,1.07519,-12.0839,-29.7941)"></path>
|
||||
<path fill="url(#c)" fill-rule="evenodd" d="M117.773,258.78l124.983,-126.586l28.844,84.924l-94.54,84.926l-59.287,-43.264Z" transform="matrix(1.07519,0,0,1.07519,-12.0839,-29.7941)"></path>
|
||||
<path fill="url(#d)" fill-rule="evenodd" d="M229.938,205.902l22.433,-75.31l123.381,124.983l-59.288,51.275l-86.526,-100.948Z" transform="matrix(1.07519,0,0,1.07519,-12.0839,-29.7941)"></path>
|
||||
<path fill="url(#e)" fill-rule="evenodd" d="M314.862,475.098l-1.602,-173.054l64.094,-48.071l1.603,221.125h-64.095Z" transform="matrix(1.07519,0,0,1.07519,-12.0839,-29.7941)"></path>
|
||||
<path fill="url(#f)" fill-rule="evenodd" stroke="#580400" stroke-linejoin="round" stroke-width="11.9213" d="M177.06,486.314l-1.602,-153.826c0,-36.854 20.029,-62.491 62.491,-62.491c44.065,0 65.697,30.444 65.697,62.491v153.826c0,0 -126.586,-1.602 -126.586,0Z" transform="matrix(1.07519,0,0,1.07519,-5.19257,-47.0224)"></path>
|
||||
<path fill="url(#g)" fill-rule="evenodd" stroke="#580400" stroke-width="11.905" d="M63.293,303.646c150.621,-144.212 150.621,-144.212 150.621,-144.212c0,0 68.901,-1.602 70.503,-1.602c1.603,0 139.405,137.802 139.405,137.802c0,0 32.048,-33.649 32.048,-33.649c0,0 -206.704,-206.704 -206.704,-206.704c0,-1.42109e-14 -216.318,214.716 -216.318,214.716c7.10543e-15,0 30.4448,33.649 30.4448,33.649Z" transform="matrix(1.07519,0,0,1.07519,-12.0839,-29.7941)"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="800" height="800" version="1.1" viewBox="0 0 800 800" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!--Generated by IJSVG (https://github.com/iconjar/IJSVG)-->
|
||||
<defs>
|
||||
<linearGradient id="b" x1="0" x2="1" gradientUnits="userSpaceOnUse" y1="0" y2="0" gradientTransform="matrix(0,1,1,0,0,200)">
|
||||
<stop offset="0%" stop-color="#D83352"></stop>
|
||||
<stop offset="50%" stop-color="#F6DC7B"></stop>
|
||||
<stop offset="100%" stop-color="#F6DC7B"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="100" y="100" width="600" height="600" fill="url(#b)"></rect>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 691 B |
@@ -1,20 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg width="120" height="120"
|
||||
viewPort="0 0 120 120" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<svg viewBox="-5 -5 10 10" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="-3" y="-3" width="6" height="6" />
|
||||
|
||||
<line stroke-linecap="butt"
|
||||
x1="30" y1="30" x2="30" y2="90"
|
||||
stroke="black" stroke-width="20"/>
|
||||
|
||||
<line stroke-linecap="round"
|
||||
x1="60" y1="30" x2="60" y2="90"
|
||||
stroke="black" stroke-width="20"/>
|
||||
|
||||
<line stroke-linecap="square"
|
||||
x1="90" y1="30" x2="90" y2="90"
|
||||
stroke="black" stroke-width="20"/>
|
||||
|
||||
<path d="M30,30 L30,90 M60,30 L60,90 M90,30 L90,90"
|
||||
stroke="white" />
|
||||
</svg>
|
||||
<rect x="-3" y="-3" width="6" height="6" fill="red"
|
||||
transform="skewY(30)" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 593 B After Width: | Height: | Size: 203 B |
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="269" height="269" version="1.1" viewBox="0 0 269 269" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!--Generated by IJSVG (https://github.com/iconjar/IJSVG)-->
|
||||
<defs>
|
||||
<mask id="a" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox">
|
||||
<use fill="#FFF" xlink:href="#d"></use>
|
||||
</mask>
|
||||
<linearGradient id="b" x1="0" x2="1" gradientUnits="userSpaceOnUse" y1="0" y2="0" gradientTransform="matrix(0,-197.994,-197.994,0,101.4,199.62)">
|
||||
<stop offset="0%" stop-color="#D83352"></stop>
|
||||
<stop offset="41.2669%" stop-color="#F6DC7B"></stop>
|
||||
<stop offset="100%" stop-color="#F6DC7B"></stop>
|
||||
</linearGradient>
|
||||
<mask id="c" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox">
|
||||
<path fill="#FFF" d="M0,202h202v-202h-202Z"></path>
|
||||
</mask>
|
||||
<path id="d" d="M2.404,100.624c0,-54.674 44.321,-98.998 98.995,-98.998v-4.88498e-15c54.675,0 98.997,44.324 98.997,98.998v0c0,54.674 -44.322,98.996 -98.997,98.996v0c-54.674,0 -98.995,-44.322 -98.995,-98.996"></path>
|
||||
</defs>
|
||||
<g transform="scale(0.998762)">
|
||||
<g transform="matrix(1.33333,0,0,-1.33333,0,269.333)">
|
||||
<use mask="url(#a)" fill="url(#b)" stroke="none" xlink:href="#d"></use>
|
||||
<g mask="url(#c)">
|
||||
<path fill="#231F20" stroke="none" d="M0,0c0,-6.725 -5.451,-12.175 -12.177,-12.175c-6.725,0 -12.176,5.45 -12.176,12.175c0,6.725 5.451,12.178 12.176,12.178c6.726,0 12.177,-5.453 12.177,-12.178" transform="matrix(1,0,0,1,75.0225,94.2754)"></path>
|
||||
<path fill="none" stroke="#231F20" stroke-linecap="round" stroke-width="9" d="M0,0c14.428,-16.873 42.352,-15.393 42.352,-15.393" transform="matrix(1,0,0,1,41.2588,117.041)"></path>
|
||||
<path fill="#231F20" stroke="none" d="M0,0c0,-6.725 -5.453,-12.176 -12.178,-12.176c-6.724,0 -12.176,5.451 -12.176,12.176c0,6.725 5.452,12.178 12.176,12.178c6.725,0 12.178,-5.453 12.178,-12.178" transform="matrix(1,0,0,1,146.952,94.3281)"></path>
|
||||
<path fill="none" stroke="#231F20" stroke-linecap="round" stroke-width="9" d="M0,0c-14.428,-16.873 -42.352,-15.393 -42.352,-15.393" transform="matrix(1,0,0,1,161.54,117.094)"></path>
|
||||
<path fill="none" stroke="#231F20" stroke-linecap="round" stroke-width="10" d="M0,0c29.782,24.805 58.656,-1.05 58.656,-1.05" transform="matrix(1,0,0,1,72.0713,41.6172)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
+11
-12
@@ -14,6 +14,9 @@
|
||||
#import "IJSVGImageLayer.h"
|
||||
#import "IJSVGExporter.h"
|
||||
#import "IJSVGRendering.h"
|
||||
#import "IJSVGColorList.h"
|
||||
#import "IJSVGGradientLayer.h"
|
||||
#import "IJSVGRenderingStyle.h"
|
||||
|
||||
@class IJSVG;
|
||||
@class IJSVGQuartzRenderer;
|
||||
@@ -68,13 +71,9 @@ withSVGString:(NSString *)subSVGString;
|
||||
|
||||
// global overwriting rules for when rendering an SVG, this will overide any
|
||||
// fillColor, strokeColor, pattern and gradient fill
|
||||
@property (nonatomic, retain) NSColor * fillColor;
|
||||
@property (nonatomic, retain) NSColor * strokeColor;
|
||||
@property (nonatomic, assign) CGFloat strokeWidth;
|
||||
@property (nonatomic, assign) IJSVGLineCapStyle lineCapStyle;
|
||||
@property (nonatomic, assign) IJSVGLineJoinStyle lineJoinStyle;
|
||||
@property (nonatomic, assign) IJSVGRenderQuality renderQuality;
|
||||
@property (nonatomic, assign) BOOL clipToViewport;
|
||||
@property (nonatomic, retain) IJSVGRenderingStyle * style;
|
||||
|
||||
- (void)prepForDrawingInView:(NSView *)view;
|
||||
- (BOOL)isFont;
|
||||
@@ -140,6 +139,9 @@ withSVGString:(NSString *)subSVGString;
|
||||
error:(NSError **)error;
|
||||
- (NSImage *)imageWithSize:(NSSize)aSize
|
||||
flipped:(BOOL)flipped;
|
||||
- (NSImage *)imageByMaintainingAspectRatioWithSize:(NSSize)aSize
|
||||
flipped:(BOOL)flipped
|
||||
error:(NSError **)error;
|
||||
- (BOOL)drawAtPoint:(NSPoint)point
|
||||
size:(NSSize)size;
|
||||
- (BOOL)drawAtPoint:(NSPoint)point
|
||||
@@ -160,12 +162,9 @@ withSVGString:(NSString *)subSVGString;
|
||||
- (void)beginVectorDraw;
|
||||
- (void)endVectorDraw;
|
||||
|
||||
// colors
|
||||
- (NSArray<NSColor *> *)visibleColors;
|
||||
- (void)setReplacementColors:(NSDictionary<NSColor *, NSColor *> *)colors;
|
||||
- (void)removeReplacementColor:(NSColor *)color;
|
||||
- (void)replaceColor:(NSColor *)color
|
||||
withColor:(NSColor *)newColor;
|
||||
- (void)removeAllReplacementColors;
|
||||
- (NSRect)computeOriginalDrawingFrameWithSize:(NSSize)aSize;
|
||||
- (void)setNeedsDisplay;
|
||||
|
||||
// colors
|
||||
- (IJSVGColorList *)computedColorList:(BOOL *)hasPatternFills;
|
||||
@end
|
||||
|
||||
+113
-103
@@ -13,25 +13,20 @@
|
||||
|
||||
@implementation IJSVG
|
||||
|
||||
@synthesize fillColor;
|
||||
@synthesize strokeColor;
|
||||
@synthesize strokeWidth;
|
||||
@synthesize lineCapStyle;
|
||||
@synthesize lineJoinStyle;
|
||||
@synthesize renderingBackingScaleHelper;
|
||||
@synthesize clipToViewport;
|
||||
@synthesize renderQuality;
|
||||
@synthesize style = _style;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
IJSVGBeginTransactionLock();
|
||||
[renderingBackingScaleHelper release], renderingBackingScaleHelper = nil;
|
||||
[fillColor release], fillColor = nil;
|
||||
[strokeColor release], strokeColor = nil;
|
||||
[_group release], _group = nil;
|
||||
[_layerTree release], _layerTree = nil;
|
||||
[_replacementColors release], _replacementColors = nil;
|
||||
[_quartzRenderer release], _quartzRenderer = nil;
|
||||
[_style release], _style = nil;
|
||||
[super dealloc];
|
||||
IJSVGEndTransactionLock();
|
||||
}
|
||||
@@ -39,14 +34,14 @@
|
||||
+ (id)svgNamed:(NSString *)string
|
||||
error:(NSError **)error
|
||||
{
|
||||
return [[self class] svgNamed:string
|
||||
return [self.class svgNamed:string
|
||||
error:error
|
||||
delegate:nil];
|
||||
}
|
||||
|
||||
+ (id)svgNamed:(NSString *)string
|
||||
{
|
||||
return [[self class] svgNamed:string
|
||||
return [self.class svgNamed:string
|
||||
error:nil];
|
||||
}
|
||||
|
||||
@@ -54,7 +49,7 @@
|
||||
useCache:(BOOL)useCache
|
||||
delegate:(id<IJSVGDelegate>)delegate
|
||||
{
|
||||
return [[self class] svgNamed:string
|
||||
return [self.class svgNamed:string
|
||||
useCache:useCache
|
||||
error:nil
|
||||
delegate:delegate];
|
||||
@@ -63,7 +58,7 @@
|
||||
+ (id)svgNamed:(NSString *)string
|
||||
delegate:(id<IJSVGDelegate>)delegate
|
||||
{
|
||||
return [[self class] svgNamed:string
|
||||
return [self.class svgNamed:string
|
||||
error:nil
|
||||
delegate:delegate];
|
||||
}
|
||||
@@ -83,7 +78,7 @@
|
||||
error:(NSError **)error
|
||||
delegate:(id<IJSVGDelegate>)delegate
|
||||
{
|
||||
NSBundle * bundle = [NSBundle mainBundle];
|
||||
NSBundle * bundle = NSBundle.mainBundle;
|
||||
NSString * str = nil;
|
||||
NSString * ext = [string pathExtension];
|
||||
if( ext == nil || ext.length == 0 ) {
|
||||
@@ -338,8 +333,9 @@
|
||||
|
||||
- (void)_setupBasicsFromAnyInitializer
|
||||
{
|
||||
self.style = [[[IJSVGRenderingStyle alloc] init] autorelease];
|
||||
self.clipToViewport = YES;
|
||||
self.renderQuality = IJSVGRenderQualityOptimized;
|
||||
self.renderQuality = IJSVGRenderQualityFullResolution;
|
||||
|
||||
// setup low level backing scale
|
||||
_lastProposedBackingScale = 0.f;
|
||||
@@ -416,6 +412,16 @@
|
||||
error:nil];
|
||||
}
|
||||
|
||||
- (NSRect)computeOriginalDrawingFrameWithSize:(NSSize)aSize
|
||||
{
|
||||
[self _beginDraw:(NSRect) {
|
||||
.origin = CGPointZero,
|
||||
.size = aSize
|
||||
}];
|
||||
return NSMakeRect(0.f, 0.f, _proposedViewSize.width * _clipScale,
|
||||
_proposedViewSize.height * _clipScale);
|
||||
}
|
||||
|
||||
- (NSImage *)imageWithSize:(NSSize)aSize
|
||||
flipped:(BOOL)flipped
|
||||
error:(NSError **)error
|
||||
@@ -436,6 +442,16 @@
|
||||
return im;
|
||||
}
|
||||
|
||||
- (NSImage *)imageByMaintainingAspectRatioWithSize:(NSSize)aSize
|
||||
flipped:(BOOL)flipped
|
||||
error:(NSError **)error
|
||||
{
|
||||
NSRect rect = [self computeOriginalDrawingFrameWithSize:aSize];
|
||||
return [self imageWithSize:rect.size
|
||||
flipped:flipped
|
||||
error:error];
|
||||
}
|
||||
|
||||
- (NSData *)PDFData
|
||||
{
|
||||
return [self PDFData:nil];
|
||||
@@ -643,9 +659,8 @@
|
||||
}
|
||||
|
||||
// add the origin back onto the viewport
|
||||
viewPort.origin.x -= round((_viewBox.origin.x)*_scale);
|
||||
viewPort.origin.y -= round((_viewBox.origin.y)*_scale);
|
||||
viewPort = CGRectIntegral(viewPort);
|
||||
viewPort.origin.x -= (_viewBox.origin.x)*_scale;
|
||||
viewPort.origin.y -= (_viewBox.origin.y)*_scale;
|
||||
|
||||
// transforms
|
||||
CGContextTranslateCTM( ref, viewPort.origin.x, viewPort.origin.y);
|
||||
@@ -699,6 +714,10 @@
|
||||
scale = 1.f;
|
||||
}
|
||||
|
||||
// make sure we multiple the scale by the scale of the rendered clip
|
||||
// or it will be blurry for gradients and other bitmap drawing
|
||||
scale = (_scale * scale);
|
||||
|
||||
// dont do anything, nothing has changed, no point of iterating over
|
||||
// every layer for no reason!
|
||||
if(scale == _lastProposedBackingScale && renderQuality == _lastProposedRenderQuality) {
|
||||
@@ -724,42 +743,6 @@
|
||||
|
||||
}
|
||||
|
||||
- (void)setFillColor:(NSColor *)aColor
|
||||
{
|
||||
if(fillColor != nil) {
|
||||
[fillColor release], fillColor = nil;
|
||||
}
|
||||
fillColor = [aColor retain];
|
||||
[_layerTree release], _layerTree = nil;
|
||||
}
|
||||
|
||||
- (void)setStrokeColor:(NSColor *)aColor
|
||||
{
|
||||
if(strokeColor != nil) {
|
||||
[strokeColor release], strokeColor = nil;
|
||||
}
|
||||
strokeColor = [aColor retain];
|
||||
[_layerTree release], _layerTree = nil;
|
||||
}
|
||||
|
||||
- (void)setStrokeWidth:(CGFloat)aWidth
|
||||
{
|
||||
strokeWidth = aWidth;
|
||||
[_layerTree release], _layerTree = nil;
|
||||
}
|
||||
|
||||
- (void)setLineCapStyle:(IJSVGLineCapStyle)aLineCapStyle
|
||||
{
|
||||
lineCapStyle = aLineCapStyle;
|
||||
[_layerTree release], _layerTree = nil;
|
||||
}
|
||||
|
||||
- (void)setLineJoinStyle:(IJSVGLineJoinStyle)aLineJoinStyle
|
||||
{
|
||||
lineJoinStyle = aLineJoinStyle;
|
||||
[_layerTree release], _layerTree = nil;
|
||||
}
|
||||
|
||||
- (IJSVGLayer *)layerWithTree:(IJSVGLayerTree *)tree
|
||||
{
|
||||
// clear memory
|
||||
@@ -784,41 +767,104 @@
|
||||
// from this SVG object
|
||||
IJSVGLayerTree * renderer = [[[IJSVGLayerTree alloc] init] autorelease];
|
||||
renderer.viewBox = self.viewBox;
|
||||
renderer.fillColor = self.fillColor;
|
||||
renderer.strokeColor = self.strokeColor;
|
||||
renderer.strokeWidth = self.strokeWidth;
|
||||
renderer.lineCapStyle = self.lineCapStyle;
|
||||
renderer.lineJoinStyle = self.lineJoinStyle;
|
||||
renderer.replacementColors = _replacementColors;
|
||||
renderer.style = self.style;
|
||||
|
||||
// return the rendered layer
|
||||
return [self layerWithTree:renderer];
|
||||
}
|
||||
|
||||
- (NSArray<NSColor *> *)visibleColors
|
||||
- (void)setStyle:(IJSVGRenderingStyle *)style
|
||||
{
|
||||
// set for the colors
|
||||
NSMutableSet * colors = [[[NSMutableSet alloc] init] autorelease];
|
||||
|
||||
// block to find colors in stroke and fill
|
||||
[self removeStyleObservers];
|
||||
[_style release], _style = nil;
|
||||
_style = style.retain;
|
||||
[self addStyleObservers];
|
||||
}
|
||||
|
||||
- (void)removeStyleObservers
|
||||
{
|
||||
for(NSString * propertyName in IJSVGRenderingStyle.observableProperties) {
|
||||
@try {
|
||||
[_style removeObserver:self
|
||||
forKeyPath:propertyName];
|
||||
} @catch(NSException * e) {}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addStyleObservers
|
||||
{
|
||||
for(NSString * propertyName in IJSVGRenderingStyle.observableProperties) {
|
||||
[_style addObserver:self
|
||||
forKeyPath:propertyName
|
||||
options:0
|
||||
context:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
|
||||
context:(void *)context
|
||||
{
|
||||
// invalidate the tree if a style is set
|
||||
if(object == _style) {
|
||||
[self invalidateLayerTree];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setNeedsDisplay
|
||||
{
|
||||
[self invalidateLayerTree];
|
||||
}
|
||||
|
||||
- (void)invalidateLayerTree
|
||||
{
|
||||
[_layerTree release], _layerTree = nil;
|
||||
}
|
||||
|
||||
- (IJSVGColorList *)computedColorList:(BOOL *)hasPatternFills
|
||||
{
|
||||
IJSVGColorList * sheet = [[[IJSVGColorList alloc] init] autorelease];
|
||||
void (^block)(CALayer * layer, BOOL isMask) = ^void (CALayer * layer, BOOL isMask) {
|
||||
if([layer isKindOfClass:[IJSVGShapeLayer class]] && isMask == NO && layer.isHidden == NO) {
|
||||
IJSVGShapeLayer * sLayer = (IJSVGShapeLayer *)layer;
|
||||
NSColor * color = nil;
|
||||
if(sLayer.fillColor != nil) {
|
||||
color = [NSColor colorWithCGColor:sLayer.fillColor];
|
||||
color = [IJSVGColor computeColorSpace:color];
|
||||
if(color.alphaComponent != 0.f) {
|
||||
[colors addObject:color];
|
||||
[sheet addColor:color];
|
||||
}
|
||||
}
|
||||
if(sLayer.strokeColor != nil) {
|
||||
color = [NSColor colorWithCGColor:sLayer.strokeColor];
|
||||
color = [IJSVGColor computeColorSpace:color];
|
||||
if(color.alphaComponent != 0.f) {
|
||||
[colors addObject:color];
|
||||
[sheet addColor:color];
|
||||
}
|
||||
}
|
||||
|
||||
// check for any patterns
|
||||
if(sLayer.patternFillLayer != nil ||
|
||||
sLayer.gradientFillLayer != nil ||
|
||||
sLayer.gradientStrokeLayer != nil ||
|
||||
sLayer.patternStrokeLayer != nil) {
|
||||
if(hasPatternFills != nil && *hasPatternFills != YES) {
|
||||
*hasPatternFills = YES;
|
||||
}
|
||||
|
||||
// add any colors from gradients
|
||||
IJSVGGradientLayer * gradLayer = nil;
|
||||
IJSVGGradientLayer * gradStrokeLayer = nil;
|
||||
if((gradLayer = sLayer.gradientFillLayer) != nil) {
|
||||
IJSVGColorList * gradSheet = gradLayer.gradient.computedColorList;
|
||||
[sheet addColorsFromList:gradSheet];
|
||||
}
|
||||
if((gradStrokeLayer = sLayer.gradientStrokeLayer) != nil) {
|
||||
IJSVGColorList * gradSheet = gradStrokeLayer.gradient.computedColorList;
|
||||
[sheet addColorsFromList:gradSheet];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -827,43 +873,7 @@
|
||||
withBlock:block];
|
||||
|
||||
// return the colours!
|
||||
return colors.allObjects;
|
||||
}
|
||||
|
||||
- (void)removeAllReplacementColors
|
||||
{
|
||||
[_replacementColors release], _replacementColors = nil;
|
||||
}
|
||||
|
||||
- (void)removeReplacementColor:(NSColor *)color
|
||||
{
|
||||
if(_replacementColors == nil) {
|
||||
return;
|
||||
}
|
||||
[_replacementColors removeObjectForKey:[IJSVGColor computeColorSpace:color]];
|
||||
}
|
||||
|
||||
- (void)replaceColor:(NSColor *)color
|
||||
withColor:(NSColor *)newColor
|
||||
{
|
||||
if(_replacementColors == nil) {
|
||||
_replacementColors = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
color = [IJSVGColor computeColorSpace:color];
|
||||
newColor = [IJSVGColor computeColorSpace:newColor];
|
||||
_replacementColors[color] = newColor;
|
||||
[_layerTree release], _layerTree = nil;
|
||||
}
|
||||
|
||||
- (void)setReplacementColors:(NSDictionary<NSColor *, NSColor *> *)colors
|
||||
{
|
||||
if(_replacementColors != nil) {
|
||||
[_replacementColors release], _replacementColors = nil;
|
||||
}
|
||||
for(NSColor * oldColor in colors) {
|
||||
[self replaceColor:oldColor
|
||||
withColor:colors[oldColor]];
|
||||
}
|
||||
return sheet;
|
||||
}
|
||||
|
||||
- (void)_beginDraw:(NSRect)rect
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ static BOOL _enabled = YES;
|
||||
|
||||
+ (IJSVG *)cachedSVGForFileURL:(NSURL *)aURL
|
||||
{
|
||||
if( ![[self class] enabled] || _cache == nil )
|
||||
if( ![self.class enabled] || _cache == nil )
|
||||
return nil;
|
||||
IJSVG * svg = nil;
|
||||
if( ( svg = [_cache objectForKey:aURL] ) == nil )
|
||||
@@ -53,7 +53,7 @@ static BOOL _enabled = YES;
|
||||
{
|
||||
_enabled = flag;
|
||||
if( !flag ) {
|
||||
[[self class] flushCache];
|
||||
[self.class flushCache];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -174,6 +174,10 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
|
||||
+ (NSColor *)colorFromString:(NSString *)string;
|
||||
+ (NSColor *)colorFromHEXString:(NSString *)string
|
||||
alpha:(CGFloat)alpha;
|
||||
+ (NSColor *)colorFromRString:(NSString *)rString
|
||||
gString:(NSString *)gString
|
||||
bString:(NSString *)bString
|
||||
aString:(NSString *)aString;
|
||||
+ (NSColor *)colorFromPredefinedColorName:(NSString *)name;
|
||||
+ (NSString *)colorNameFromPredefinedColor:(IJSVGPredefinedColor)color;
|
||||
+ (NSColor *)changeAlphaOnColor:(NSColor *)color
|
||||
|
||||
+56
-26
@@ -40,7 +40,7 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
|
||||
|
||||
+ (NSColorSpace *)defaultColorSpace
|
||||
{
|
||||
return [NSColorSpace deviceRGBColorSpace];
|
||||
return NSColorSpace.deviceRGBColorSpace;
|
||||
}
|
||||
|
||||
+ (NSColor *)computeColorSpace:(NSColor *)color
|
||||
@@ -213,6 +213,35 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSColor *)colorFromRString:(NSString *)rString
|
||||
gString:(NSString *)gString
|
||||
bString:(NSString *)bString
|
||||
aString:(NSString *)aString
|
||||
{
|
||||
return [self colorFromRUnit:[IJSVGUnitLength unitWithString:rString]
|
||||
gUnit:[IJSVGUnitLength unitWithString:gString]
|
||||
bUnit:[IJSVGUnitLength unitWithString:bString]
|
||||
aUnit:[IJSVGUnitLength unitWithString:aString]];
|
||||
}
|
||||
|
||||
+ (NSColor *)colorFromRUnit:(IJSVGUnitLength *)rUnit
|
||||
gUnit:(IJSVGUnitLength *)gUnit
|
||||
bUnit:(IJSVGUnitLength *)bUnit
|
||||
aUnit:(IJSVGUnitLength *)aUnit
|
||||
{
|
||||
CGFloat r = rUnit.type == IJSVGUnitLengthTypePercentage ?
|
||||
[rUnit computeValue:255.f] : [rUnit computeValue:1.f];
|
||||
CGFloat g = gUnit.type == IJSVGUnitLengthTypePercentage ?
|
||||
[gUnit computeValue:255.f] : [gUnit computeValue:1.f];
|
||||
CGFloat b = bUnit.type == IJSVGUnitLengthTypePercentage ?
|
||||
[bUnit computeValue:255.f] : [bUnit computeValue:1.f];
|
||||
CGFloat a = [aUnit computeValue:100.f];
|
||||
return [self computeColorSpace:[NSColor colorWithDeviceRed:(r/255.f)
|
||||
green:(g/255.f)
|
||||
blue:(b/255.f)
|
||||
alpha:a]];
|
||||
}
|
||||
|
||||
+ (NSColor *)colorFromString:(NSString *)string
|
||||
{
|
||||
NSCharacterSet * set = NSCharacterSet.whitespaceAndNewlineCharacterSet;
|
||||
@@ -231,25 +260,24 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
|
||||
}
|
||||
}
|
||||
|
||||
// is simply a clear color, dont fill
|
||||
if( [[string lowercaseString] isEqualToString:@"none"] ) {
|
||||
return [NSColor clearColor];
|
||||
return [self computeColorSpace:NSColor.clearColor];
|
||||
}
|
||||
|
||||
// is it RGB?
|
||||
if( [[string substringToIndex:3] isEqualToString:@"rgb"] ) {
|
||||
NSInteger count = 0;
|
||||
CGFloat * params = [IJSVGUtils commandParameters:string
|
||||
count:&count];
|
||||
CGFloat alpha = 1;
|
||||
if( count == 4 ) {
|
||||
alpha = params[3];
|
||||
NSRange range = [IJSVGUtils rangeOfParentheses:string];
|
||||
NSString * rgbString = [string substringWithRange:range];
|
||||
NSArray * parts = [rgbString componentsSeparatedByChars:","];
|
||||
NSString * alpha = @"100%";
|
||||
if(parts.count == 4) {
|
||||
alpha = parts[3];
|
||||
}
|
||||
color = [NSColor colorWithDeviceRed:params[0]/255.f
|
||||
green:params[1]/255.f
|
||||
blue:params[2]/255.f
|
||||
alpha:alpha];
|
||||
free(params);
|
||||
return color;
|
||||
return [self colorFromRString:parts[0]
|
||||
gString:parts[1]
|
||||
bString:parts[2]
|
||||
aString:alpha];
|
||||
}
|
||||
|
||||
// is it HSL?
|
||||
@@ -269,6 +297,8 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
|
||||
brightness:hsb[2]
|
||||
alpha:alpha];
|
||||
|
||||
color = [self computeColorSpace:color];
|
||||
|
||||
// memory clean!
|
||||
free(hsb);
|
||||
free(params);
|
||||
@@ -642,10 +672,10 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
|
||||
to:(CGFloat)alphaValue
|
||||
{
|
||||
color = [self computeColorSpace:color];
|
||||
return [NSColor colorWithDeviceRed:[color redComponent]
|
||||
green:[color greenComponent]
|
||||
blue:[color blueComponent]
|
||||
alpha:alphaValue];
|
||||
return [self computeColorSpace:[NSColor colorWithDeviceRed:[color redComponent]
|
||||
green:[color greenComponent]
|
||||
blue:[color blueComponent]
|
||||
alpha:alphaValue]];
|
||||
}
|
||||
|
||||
+ (BOOL)isColor:(NSString *)string
|
||||
@@ -668,10 +698,10 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
|
||||
|
||||
+ (NSColor *)colorFromHEXInteger:(NSInteger)hex
|
||||
{
|
||||
return [NSColor colorWithDeviceRed:((hex >> 16) & 0xFF) / 255.f
|
||||
green:((hex >> 6) & 0xFF) / 255.f
|
||||
blue:(hex & 0xFF) / 255.f
|
||||
alpha:1.f];
|
||||
return [self computeColorSpace:[NSColor colorWithDeviceRed:((hex >> 16) & 0xFF) / 255.f
|
||||
green:((hex >> 8) & 0xFF) / 255.f
|
||||
blue:(hex & 0xFF) / 255.f
|
||||
alpha:1.f]];
|
||||
}
|
||||
|
||||
+ (NSColor *)colorFromHEXString:(NSString *)string
|
||||
@@ -698,10 +728,10 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
|
||||
|
||||
const char * hexString = [string cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
unsigned long hex = strtoul(hexString, NULL, 16);
|
||||
return [NSColor colorWithDeviceRed:((hex>>16) & 0xFF)/255.f
|
||||
green:((hex>>8) & 0xFF)/255.f
|
||||
blue:(hex & 0xFF)/255.f
|
||||
alpha:alpha];
|
||||
return [self computeColorSpace:[NSColor colorWithDeviceRed:((hex>>16) & 0xFF)/255.f
|
||||
green:((hex>>8) & 0xFF)/255.f
|
||||
blue:(hex & 0xFF)/255.f
|
||||
alpha:alpha]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// IJSVGColorList.h
|
||||
// IconJar
|
||||
//
|
||||
// Created by Curtis Hard on 07/07/2019.
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "IJSVGColor.h"
|
||||
|
||||
@interface IJSVGColorList : NSObject <NSCopying> {
|
||||
|
||||
@private
|
||||
NSMutableDictionary<NSColor *, NSColor *> * _replacementColorTree;
|
||||
NSMutableSet<NSColor *> * _colors;
|
||||
}
|
||||
|
||||
- (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<NSColor *> *)colors;
|
||||
- (void)addColor:(NSColor *)color;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,113 @@
|
||||
//
|
||||
// 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
|
||||
{
|
||||
[_replacementColorTree release], _replacementColorTree = nil;
|
||||
[_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
|
||||
{
|
||||
[_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<NSColor *> *)colors
|
||||
{
|
||||
return [NSSet setWithSet:_colors];
|
||||
}
|
||||
|
||||
- (void)addColorsFromList:(IJSVGColorList *)sheet
|
||||
{
|
||||
[_colors addObjectsFromArray:sheet.colors.allObjects];
|
||||
}
|
||||
|
||||
- (void)addColor:(NSColor *)color
|
||||
{
|
||||
[_colors addObject:[IJSVGColor computeColorSpace:color]];
|
||||
}
|
||||
|
||||
- (void)removeColor:(NSColor *)color
|
||||
{
|
||||
[_colors removeObject:[IJSVGColor computeColorSpace:color]];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -50,7 +50,7 @@
|
||||
_currentIndex = 0;
|
||||
command = [[str substringToIndex:1] copy];
|
||||
type = [IJSVGUtils typeForCommandString:self.command];
|
||||
commandClass = [[self class] commandClassForCommandChar:[self.command characterAtIndex:0]];
|
||||
commandClass = [self.class commandClassForCommandChar:[self.command characterAtIndex:0]];
|
||||
parameters = [IJSVGUtils commandParameters:str count:¶meterCount];
|
||||
requiredParameters = [self.commandClass requiredParameterCount];
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
}
|
||||
|
||||
// create a subcommand per set
|
||||
IJSVGCommand * c = [[[[self class] alloc] init] autorelease];
|
||||
IJSVGCommand * c = [[[self.class alloc] init] autorelease];
|
||||
c.parameterCount = self.requiredParameters;
|
||||
c.parameters = subParams;
|
||||
c.type = self.type;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
commandPoint = CGPointMake(-1*(command.parameters[0] + oldPoint.x) + 2*([path currentSubpath].currentPoint.x),
|
||||
-1*(command.parameters[1] + oldPoint.y) + 2*[path currentSubpath].currentPoint.y);
|
||||
}
|
||||
} else if( command.commandClass == [self class] ) {
|
||||
} else if( command.commandClass == self.class ) {
|
||||
// smooth quadratic curve
|
||||
commandPoint = CGPointMake(-1*(path.lastControlPoint.x) + 2*([path currentSubpath].currentPoint.x),
|
||||
-1*(path.lastControlPoint.y) + 2*[path currentSubpath].currentPoint.y);
|
||||
|
||||
@@ -26,7 +26,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.commandClass == [self class] && currentCommand.isSubCommand == YES) {
|
||||
if( command.commandClass == self.class && currentCommand.isSubCommand == YES) {
|
||||
[IJSVGCommandLineTo runWithParams:params
|
||||
paramCount:count
|
||||
command:currentCommand
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
NSPoint firstControl = NSMakePoint( [path currentSubpath].currentPoint.x, [path currentSubpath].currentPoint.y );
|
||||
if( command != nil )
|
||||
{
|
||||
if( command.commandClass == [IJSVGCommandCurve class] || command.commandClass == [self class] )
|
||||
if( command.commandClass == [IJSVGCommandCurve class] || command.commandClass == self.class )
|
||||
{
|
||||
if( command.commandClass == [IJSVGCommandCurve class] )
|
||||
{
|
||||
|
||||
@@ -43,6 +43,8 @@ typedef NS_OPTIONS( NSInteger, IJSVGExporterOptions) {
|
||||
IJSVGExporterOptionRemoveWidthHeightAttributes
|
||||
};
|
||||
|
||||
BOOL IJSVGExporterHasOption(IJSVGExporterOptions options, NSInteger option);
|
||||
|
||||
@interface IJSVGExporter : NSObject {
|
||||
|
||||
@private
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
@synthesize title;
|
||||
@synthesize description;
|
||||
|
||||
BOOL IJSVGExporterHasOption(IJSVGExporterOptions options, NSInteger option)
|
||||
{
|
||||
return (options & option) != 0;
|
||||
};
|
||||
|
||||
const NSArray * IJSVGShortCharacterArray()
|
||||
{
|
||||
static NSArray * _array;
|
||||
@@ -928,6 +933,7 @@ NSString * IJSVGHash(NSString * key) {
|
||||
|
||||
// add the stops
|
||||
NSGradient * grad = layer.gradient.gradient;
|
||||
IJSVGColorList * sheet = layer.gradient.colorList;
|
||||
NSInteger noStops = grad.numberOfColorStops;
|
||||
for(NSInteger i = 0; i < noStops; i++) {
|
||||
|
||||
@@ -938,6 +944,10 @@ NSString * IJSVGHash(NSString * key) {
|
||||
location:&location
|
||||
atIndex:i];
|
||||
|
||||
if(sheet != nil) {
|
||||
aColor = [sheet proposedColorForColor:aColor];
|
||||
}
|
||||
|
||||
// create the stop element
|
||||
NSXMLElement * stop = [[[NSXMLElement alloc] init] autorelease];
|
||||
stop.name = @"stop";
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "IJSVGDef.h"
|
||||
#import "IJSVGTransform.h"
|
||||
#import "IJSVGColorList.h"
|
||||
|
||||
@interface IJSVGGradient : IJSVGNode
|
||||
|
||||
@@ -18,6 +19,7 @@
|
||||
@property ( nonatomic, retain ) IJSVGUnitLength * x2;
|
||||
@property ( nonatomic, retain ) IJSVGUnitLength * y1;
|
||||
@property ( nonatomic, retain ) IJSVGUnitLength * y2;
|
||||
@property ( nonatomic, retain) IJSVGColorList * colorList;
|
||||
|
||||
+ (CGFloat *)computeColorStopsFromString:(NSXMLElement *)element
|
||||
colors:(NSArray **)someColors;
|
||||
@@ -27,4 +29,10 @@
|
||||
absoluteTransform:(CGAffineTransform)absoluteTransform
|
||||
viewPort:(CGRect)viewBox;
|
||||
|
||||
- (void)_debugStart:(CGPoint)startPoint
|
||||
end:(CGPoint)endPoint
|
||||
context:(CGContextRef)ctx;
|
||||
|
||||
- (IJSVGColorList *)computedColorList;
|
||||
|
||||
@end
|
||||
|
||||
+45
-3
@@ -12,6 +12,7 @@
|
||||
|
||||
@synthesize gradient, CGGradient;
|
||||
@synthesize x1, x2, y1, y2;
|
||||
@synthesize colorList = _colorList;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
@@ -20,7 +21,8 @@
|
||||
[y1 release], y1 = nil;
|
||||
[y2 release], y2 = nil;
|
||||
[gradient release], gradient = nil;
|
||||
if( CGGradient != nil ) {
|
||||
[_colorList release], _colorList = nil;
|
||||
if(CGGradient != nil) {
|
||||
CGGradientRelease(CGGradient);
|
||||
}
|
||||
[super dealloc];
|
||||
@@ -33,6 +35,15 @@
|
||||
return clone;
|
||||
}
|
||||
|
||||
- (void)setColorList:(IJSVGColorList *)list
|
||||
{
|
||||
[_colorList release], _colorList = nil;
|
||||
_colorList = list.retain;
|
||||
if(CGGradient != nil) {
|
||||
CGGradientRelease(CGGradient);
|
||||
}
|
||||
}
|
||||
|
||||
+ (CGFloat *)computeColorStopsFromString:(NSXMLElement *)element
|
||||
colors:(NSArray **)someColors
|
||||
{
|
||||
@@ -103,6 +114,20 @@
|
||||
return stopsParams;
|
||||
}
|
||||
|
||||
- (IJSVGColorList *)computedColorList
|
||||
{
|
||||
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];
|
||||
[sheet addColor:color];
|
||||
}
|
||||
return sheet;
|
||||
}
|
||||
|
||||
- (CGGradientRef)CGGradient
|
||||
{
|
||||
// store it in the cache
|
||||
@@ -113,15 +138,20 @@
|
||||
// actually create the gradient
|
||||
NSInteger num = self.gradient.numberOfColorStops;
|
||||
CGFloat * locations = malloc(sizeof(CGFloat)*num);
|
||||
CFMutableArrayRef colors = CFArrayCreateMutable(kCFAllocatorDefault, (CFIndex)num, &kCFTypeArrayCallBacks);
|
||||
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(_colorList != nil) {
|
||||
color = [_colorList proposedColorForColor:color];
|
||||
}
|
||||
CFArrayAppendValue(colors, color.CGColor);
|
||||
}
|
||||
CGGradientRef result = CGGradientCreateWithColors(self.gradient.colorSpace.CGColorSpace, colors, locations);
|
||||
CGGradientRef result = CGGradientCreateWithColors(self.gradient.colorSpace.CGColorSpace,
|
||||
colors, locations);
|
||||
CFRelease(colors);
|
||||
free(locations);
|
||||
return CGGradient = result;
|
||||
@@ -134,4 +164,16 @@
|
||||
{
|
||||
}
|
||||
|
||||
- (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
|
||||
|
||||
@@ -65,11 +65,11 @@
|
||||
{
|
||||
switch (self.renderQuality) {
|
||||
case IJSVGRenderQualityOptimized: {
|
||||
backingScaleFactor = .35f;
|
||||
backingScaleFactor = (backingScaleFactor * .35f);
|
||||
break;
|
||||
}
|
||||
case IJSVGRenderQualityLow: {
|
||||
backingScaleFactor = .05f;
|
||||
backingScaleFactor = (backingScaleFactor * .05f);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
+ (instancetype)imageRepWithData:(NSData *)data
|
||||
{
|
||||
return [[self alloc] initWithData:data];
|
||||
return [[[self alloc] initWithData:data] autorelease];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import "IJSVGNode.h"
|
||||
#import "IJSVGRenderingStyle.h"
|
||||
|
||||
@class IJSVGLayer;
|
||||
|
||||
@@ -16,12 +17,8 @@
|
||||
}
|
||||
|
||||
@property (nonatomic, assign) CGRect viewBox;
|
||||
@property (nonatomic, retain) NSColor * fillColor;
|
||||
@property (nonatomic, retain) NSColor * strokeColor;
|
||||
@property (nonatomic, assign) CGFloat strokeWidth;
|
||||
@property (nonatomic, assign) IJSVGLineJoinStyle lineJoinStyle;
|
||||
@property (nonatomic, assign) IJSVGLineCapStyle lineCapStyle;
|
||||
@property (nonatomic, retain) NSDictionary<NSColor *, NSColor *> * replacementColors;
|
||||
@property (nonatomic, retain) IJSVGRenderingStyle * style;
|
||||
|
||||
|
||||
- (IJSVGLayer *)layerForNode:(IJSVGNode *)node;
|
||||
|
||||
|
||||
+32
-62
@@ -27,26 +27,17 @@
|
||||
@implementation IJSVGLayerTree
|
||||
|
||||
@synthesize viewBox;
|
||||
@synthesize fillColor;
|
||||
@synthesize strokeColor;
|
||||
@synthesize strokeWidth;
|
||||
@synthesize lineJoinStyle;
|
||||
@synthesize lineCapStyle;
|
||||
@synthesize replacementColors;
|
||||
@synthesize style = _style;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[fillColor release], fillColor = nil;
|
||||
[strokeColor release], strokeColor = nil;
|
||||
[replacementColors release], replacementColors = nil;
|
||||
[_style release], _style = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if((self = [super init]) != nil) {
|
||||
self.lineJoinStyle = IJSVGLineJoinStyleNone;
|
||||
self.lineCapStyle = IJSVGLineCapStyleNone;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -253,20 +244,15 @@
|
||||
{
|
||||
CGAffineTransform parentAbsoluteTransform = CGAffineTransformIdentity;
|
||||
IJSVGNode * intermediateNode = node.intermediateParentNode;
|
||||
node = node.parentNode;
|
||||
while(node != nil) {
|
||||
// intermediateParent should be skipped as these are elements
|
||||
// created by use statements and are technically fake elements, but the
|
||||
// spec says use them for the transforms, yolo!
|
||||
IJSVGNode * parentSVGNode = node;
|
||||
while((parentSVGNode = parentSVGNode.parentNode) != nil) {
|
||||
if(node == intermediateNode) {
|
||||
node = node.parentNode;
|
||||
continue;
|
||||
}
|
||||
CGAffineTransform trans = IJSVGConcatTransforms(node.transforms);
|
||||
parentAbsoluteTransform = CGAffineTransformConcat(trans,parentAbsoluteTransform);
|
||||
node = node.parentNode;
|
||||
parentAbsoluteTransform = [self absoluteTransform:parentSVGNode];
|
||||
}
|
||||
return parentAbsoluteTransform;
|
||||
return CGAffineTransformConcat(IJSVGConcatTransforms(node.transforms),
|
||||
parentAbsoluteTransform);
|
||||
}
|
||||
|
||||
- (IJSVGLayer *)layerForPath:(IJSVGPath *)path
|
||||
@@ -281,7 +267,7 @@
|
||||
path.strokeGradient != nil);
|
||||
|
||||
// any gradient?
|
||||
if(self.fillColor == nil && path.fillGradient != nil) {
|
||||
if(_style.fillColor == nil && path.fillGradient != nil) {
|
||||
|
||||
// create the gradient
|
||||
IJSVGGradientLayer * gradLayer = [self gradientLayerForLayer:layer
|
||||
@@ -294,7 +280,7 @@
|
||||
[layer addSublayer:gradLayer];
|
||||
layer.gradientFillLayer = gradLayer;
|
||||
|
||||
} else if(self.fillColor == nil && path.fillPattern != nil) {
|
||||
} else if(_style.fillColor == nil && path.fillPattern != nil) {
|
||||
|
||||
// create the pattern, this is actually not as easy as it may seem
|
||||
IJSVGPatternLayer * patternLayer = [self patternLayerForLayer:layer
|
||||
@@ -316,29 +302,29 @@
|
||||
NSColor * fColor = path.fillColor;
|
||||
BOOL hasColor = (fColor.alphaComponent == 0.f || fColor == nil) == NO;
|
||||
BOOL hasFill = path.fillPattern != nil || path.fillGradient != nil;
|
||||
if(self.fillColor && (hasFill || hasColor || fColor == nil)) {
|
||||
fColor = self.fillColor;
|
||||
if(_style.fillColor && (hasFill || hasColor || fColor == nil)) {
|
||||
fColor = _style.fillColor;
|
||||
} else if(fColor != nil && path.fillOpacity.value != 1.f) {
|
||||
fColor = [IJSVGColor changeAlphaOnColor:fColor
|
||||
to:path.fillOpacity.value];
|
||||
}
|
||||
|
||||
// anything changed by user?
|
||||
fColor = [self proposedColorForColor:fColor];
|
||||
fColor = [_style.colorList proposedColorForColor:fColor];
|
||||
|
||||
// just set the color
|
||||
if(fColor != nil) {
|
||||
layer.fillColor = fColor.CGColor;
|
||||
} else {
|
||||
// use default color
|
||||
NSColor * defColor = [NSColor blackColor];
|
||||
NSColor * defColor = [IJSVGColor computeColorSpace:NSColor.blackColor];
|
||||
if(path.fillOpacity.value != 1.f) {
|
||||
defColor = [IJSVGColor changeAlphaOnColor:defColor
|
||||
to:path.fillOpacity.value];
|
||||
}
|
||||
|
||||
// work out if anything was changed by user
|
||||
NSColor * proposedColor = [self proposedColorForColor:defColor];
|
||||
NSColor * proposedColor = [_style.colorList proposedColorForColor:defColor];
|
||||
layer.fillColor = proposedColor.CGColor;
|
||||
}
|
||||
}
|
||||
@@ -352,11 +338,11 @@
|
||||
|
||||
// reset the node
|
||||
BOOL moveStrokeLayer = NO;
|
||||
if(self.strokeColor == nil && path.strokeGradient != nil) {
|
||||
if(_style.strokeColor == nil && path.strokeGradient != nil) {
|
||||
|
||||
// force reset of the mask colour as we need to use the stroke layer
|
||||
// as the mask for the stroke gradient
|
||||
strokeLayer.strokeColor = [NSColor blackColor].CGColor;
|
||||
strokeLayer.strokeColor = [IJSVGColor computeColorSpace:NSColor.blackColor].CGColor;
|
||||
|
||||
// create the gradient
|
||||
IJSVGGradientLayer * gradLayer = [self gradientStrokeLayerForLayer:layer
|
||||
@@ -373,10 +359,10 @@
|
||||
layer.strokeLayer = strokeLayer;
|
||||
layer.gradientStrokeLayer = gradLayer;
|
||||
|
||||
} else if(self.strokeColor == nil && path.strokePattern != nil) {
|
||||
} else if(_style.strokeColor == nil && path.strokePattern != nil) {
|
||||
|
||||
// force reset of the mask
|
||||
strokeLayer.strokeColor = [NSColor blackColor].CGColor;
|
||||
strokeLayer.strokeColor = [IJSVGColor computeColorSpace:NSColor.blackColor].CGColor;
|
||||
|
||||
// create the pattern
|
||||
IJSVGPatternLayer * patternLayer = [self patternStrokeLayerForLayer:layer
|
||||
@@ -432,24 +418,6 @@
|
||||
return bounds;
|
||||
}
|
||||
|
||||
- (NSColor *)proposedColorForColor:(NSColor *)color
|
||||
{
|
||||
// nothing found, just return color
|
||||
if(replacementColors == nil || replacementColors.count == 0) {
|
||||
return color;
|
||||
}
|
||||
|
||||
// check the mappings
|
||||
NSColor * found = nil;
|
||||
color = [IJSVGColor computeColorSpace:color];
|
||||
if((found = replacementColors[color]) != nil) {
|
||||
return found;
|
||||
}
|
||||
|
||||
// nothing :(
|
||||
return color;
|
||||
}
|
||||
|
||||
- (IJSVGGradientLayer *)gradientStrokeLayerForLayer:(IJSVGShapeLayer *)layer
|
||||
gradient:(IJSVGGradient *)gradient
|
||||
fromNode:(IJSVGNode *)path
|
||||
@@ -477,12 +445,14 @@
|
||||
shouldMask:(BOOL)shouldMask
|
||||
{
|
||||
// the gradient drawing layer
|
||||
gradient.colorList = _style.colorList;
|
||||
IJSVGGradientLayer * gradLayer = [[[IJSVGGradientLayer alloc] init] autorelease];
|
||||
gradLayer.viewBox = self.viewBox;
|
||||
gradLayer.frame = layer.bounds;
|
||||
gradLayer.gradient = gradient;
|
||||
gradLayer.absoluteTransform = [self absoluteTransform:path];
|
||||
gradLayer.objectRect = CGRectApplyAffineTransform(objectRect, gradLayer.absoluteTransform);
|
||||
gradLayer.objectRect = CGRectApplyAffineTransform(objectRect,
|
||||
gradLayer.absoluteTransform);
|
||||
|
||||
if(shouldMask == YES) {
|
||||
// add the mask
|
||||
@@ -589,13 +559,13 @@
|
||||
// same as fill, dont use global if the alpha is 0.f, but do use it
|
||||
// if there is a pattern or gradient
|
||||
NSColor * sColor = path.strokeColor;
|
||||
if(self.strokeColor != nil &&
|
||||
if(_style.strokeColor != nil &&
|
||||
((sColor != nil && sColor.alphaComponent != 0.f) ||
|
||||
path.strokePattern != nil || path.strokeGradient != nil )) {
|
||||
sColor = self.strokeColor;
|
||||
sColor = _style.strokeColor;
|
||||
}
|
||||
|
||||
sColor = [self proposedColorForColor:sColor];
|
||||
sColor = [_style.colorList proposedColorForColor:sColor];
|
||||
|
||||
// stroke layer
|
||||
IJSVGStrokeLayer * strokeLayer = [[[IJSVGStrokeLayer alloc] init] autorelease];
|
||||
@@ -604,9 +574,9 @@
|
||||
strokeLayer.strokeColor = sColor.CGColor;
|
||||
|
||||
CGFloat lineWidth = 1.f;
|
||||
if(self.strokeWidth > 0.f) {
|
||||
lineWidth = self.strokeWidth;
|
||||
} else if(path.strokeWidth.value > 0.f) {
|
||||
if(_style.lineWidth != IJSVGInheritedFloatValue) {
|
||||
lineWidth = _style.lineWidth;
|
||||
} else {
|
||||
lineWidth = path.strokeWidth.value;
|
||||
}
|
||||
|
||||
@@ -615,15 +585,15 @@
|
||||
IJSVGLineJoinStyle lJoinStyle;
|
||||
|
||||
// forced cap style
|
||||
if(self.lineCapStyle != IJSVGLineCapStyleNone) {
|
||||
lCapStyle = self.lineCapStyle;
|
||||
if(_style.lineCapStyle != IJSVGLineCapStyleNone) {
|
||||
lCapStyle = _style.lineCapStyle;
|
||||
} else {
|
||||
lCapStyle = path.lineCapStyle;
|
||||
}
|
||||
|
||||
// forced join style
|
||||
if(self.lineJoinStyle != IJSVGLineJoinStyleNone) {
|
||||
lJoinStyle = self.lineJoinStyle;
|
||||
if(_style.lineJoinStyle != IJSVGLineJoinStyleNone) {
|
||||
lJoinStyle = _style.lineJoinStyle;
|
||||
} else {
|
||||
lJoinStyle = path.lineJoinStyle;
|
||||
}
|
||||
@@ -681,7 +651,7 @@
|
||||
|
||||
// recursive colourize for each item
|
||||
[self _recursiveColorLayersFromLayer:maskLayer
|
||||
withColor:[NSColor whiteColor].CGColor];
|
||||
withColor:[IJSVGColor computeColorSpace:NSColor.whiteColor].CGColor];
|
||||
|
||||
// add the mask
|
||||
layer.mask = maskLayer;
|
||||
|
||||
@@ -14,38 +14,19 @@
|
||||
+ (NSGradient *)parseGradient:(NSXMLElement *)element
|
||||
gradient:(IJSVGLinearGradient *)aGradient
|
||||
{
|
||||
|
||||
CGFloat px1 = [[element attributeForName:@"x1"] stringValue].floatValue;
|
||||
CGFloat px2 = [[element attributeForName:@"x2"] stringValue].floatValue;
|
||||
CGFloat py1 = [[element attributeForName:@"y1"] stringValue].floatValue;
|
||||
CGFloat py2 = [[element attributeForName:@"y2"] stringValue].floatValue;
|
||||
|
||||
// work out each coord, and work out if its a % or not
|
||||
// annoyingly we need to check them all against each other -_-
|
||||
BOOL isPercent = NO;
|
||||
if((px1 >= 0.f && px1 <= 1.f) && (px2 >= 0.f && px2 <= 1.f) &&
|
||||
(py1 >= 0.f && py1 <= 1.f) && (py2 >= 0.f && py2 <= 1.f)) {
|
||||
isPercent = YES;
|
||||
}
|
||||
|
||||
// assume its a vertical / horizonal
|
||||
if(isPercent == NO) {
|
||||
// just ask unit for the value
|
||||
aGradient.x1 = [IJSVGGradientUnitLength unitWithString:[[element attributeForName:@"x1"] stringValue] ?: @"0"];
|
||||
aGradient.x2 = [IJSVGGradientUnitLength unitWithString:[[element attributeForName:@"x2"] stringValue] ?: @"100"];
|
||||
aGradient.y1 = [IJSVGGradientUnitLength unitWithString:[[element attributeForName:@"y1"] stringValue] ?: @"0"];
|
||||
aGradient.y2 = [IJSVGGradientUnitLength unitWithString:[[element attributeForName:@"y2"] stringValue] ?: @"0"];
|
||||
} else {
|
||||
// make sure its a percent!
|
||||
aGradient.x1 = [IJSVGGradientUnitLength unitWithPercentageString:[[element attributeForName:@"x1"] stringValue] ?: @"0"];
|
||||
aGradient.x2 = [IJSVGGradientUnitLength unitWithPercentageString:[[element attributeForName:@"x2"] stringValue] ?: @"1"];
|
||||
aGradient.y1 = [IJSVGGradientUnitLength unitWithPercentageString:[[element attributeForName:@"y1"] stringValue] ?: @"0"];
|
||||
aGradient.y2 = [IJSVGGradientUnitLength unitWithPercentageString:[[element attributeForName:@"y2"] stringValue] ?: @"0"];
|
||||
}
|
||||
// just ask unit for the value
|
||||
NSString * x1 = ([element attributeForName:@"x1"].stringValue ?: @"0");
|
||||
NSString * x2 = ([element attributeForName:@"x2"].stringValue ?: @"100%");
|
||||
NSString * y1 = ([element attributeForName:@"y1"].stringValue ?: @"0");
|
||||
NSString * y2 = ([element attributeForName:@"y2"].stringValue ?: @"0");
|
||||
aGradient.x1 = [IJSVGGradientUnitLength unitWithString:x1 fromUnitType:aGradient.units];
|
||||
aGradient.x2 = [IJSVGGradientUnitLength unitWithString:x2 fromUnitType:aGradient.units];
|
||||
aGradient.y1 = [IJSVGGradientUnitLength unitWithString:y1 fromUnitType:aGradient.units];
|
||||
aGradient.y2 = [IJSVGGradientUnitLength unitWithString:y2 fromUnitType:aGradient.units];
|
||||
|
||||
// compute the color stops and colours
|
||||
NSArray * colors = nil;
|
||||
CGFloat * stopsParams = [[self class] computeColorStopsFromString:element
|
||||
CGFloat * stopsParams = [self.class computeColorStopsFromString:element
|
||||
colors:&colors];
|
||||
|
||||
// create the gradient with the colours
|
||||
@@ -66,41 +47,40 @@
|
||||
|
||||
CGPoint gradientStartPoint = CGPointZero;
|
||||
CGPoint gradientEndPoint = CGPointZero;
|
||||
CGAffineTransform absTransform = absoluteTransform;
|
||||
CGAffineTransform selfTransform = IJSVGConcatTransforms(self.transforms);
|
||||
|
||||
#pragma mark User Space On Use
|
||||
CGRect boundingBox = inUserSpace ? viewBox : objectRect;
|
||||
|
||||
// make sure we apply the absolute position to
|
||||
// transform us back into the correct space
|
||||
if(inUserSpace == YES) {
|
||||
CGFloat width = CGRectGetWidth(viewBox);
|
||||
CGFloat height = CGRectGetHeight(viewBox);
|
||||
gradientStartPoint = CGPointMake([self.x1 computeValue:width],
|
||||
[self.y1 computeValue:height]);
|
||||
|
||||
gradientEndPoint = CGPointMake([self.x2 computeValue:width],
|
||||
[self.y2 computeValue:height]);
|
||||
|
||||
// transform absolute - due to user space
|
||||
CGContextConcatCTM(ctx, absTransform);
|
||||
} else {
|
||||
#pragma mark Object Bounding Box
|
||||
CGFloat width = CGRectGetWidth(objectRect);
|
||||
CGFloat height = CGRectGetHeight(objectRect);
|
||||
gradientStartPoint = CGPointMake([self.x1 computeValue:width],
|
||||
[self.y1 computeValue:height]);
|
||||
|
||||
gradientEndPoint = CGPointMake([self.x2 computeValue:width],
|
||||
[self.y2 computeValue:height]);
|
||||
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);
|
||||
|
||||
// draw the gradient
|
||||
CGGradientDrawingOptions options = kCGGradientDrawsBeforeStartLocation|
|
||||
CGGradientDrawingOptions options =
|
||||
kCGGradientDrawsBeforeStartLocation|
|
||||
kCGGradientDrawsAfterEndLocation;
|
||||
|
||||
CGContextDrawLinearGradient(ctx, self.CGGradient, gradientStartPoint,
|
||||
gradientEndPoint, options);
|
||||
|
||||
#ifdef IJSVG_DEBUG
|
||||
[self _debugStart:gradientStartPoint
|
||||
end:gradientEndPoint
|
||||
context:ctx];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -73,12 +73,6 @@ typedef NS_OPTIONS( NSInteger, IJSVGFontTraits ) {
|
||||
IJSVGFontTraitItalic = 1 << 2
|
||||
};
|
||||
|
||||
typedef NS_ENUM( NSInteger, IJSVGUnitType) {
|
||||
IJSVGUnitUserSpaceOnUse,
|
||||
IJSVGUnitObjectBoundingBox,
|
||||
IJSVGUnitInherit
|
||||
};
|
||||
|
||||
typedef NS_ENUM( NSInteger, IJSVGBlendMode) {
|
||||
IJSVGBlendModeNormal = kCGBlendModeNormal,
|
||||
IJSVGBlendModeMultiply = kCGBlendModeMultiply,
|
||||
|
||||
+2
-2
@@ -204,7 +204,7 @@
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
IJSVGNode * node = [[self class] allocWithZone:zone];
|
||||
IJSVGNode * node = [self.class allocWithZone:zone];
|
||||
[node applyPropertiesFromNode:self];
|
||||
return node;
|
||||
}
|
||||
@@ -223,7 +223,7 @@
|
||||
self.strokeOpacity = [IJSVGUnitLength unitWithFloat:1.f];
|
||||
self.strokeOpacity.inherit = YES;
|
||||
|
||||
self.strokeWidth = [IJSVGUnitLength unitWithFloat:0.f];
|
||||
self.strokeWidth = [IJSVGUnitLength unitWithFloat:1.f];
|
||||
self.strokeWidth.inherit = YES;
|
||||
|
||||
self.windingRule = IJSVGWindingRuleInherit;
|
||||
|
||||
+11
-16
@@ -16,7 +16,7 @@
|
||||
|
||||
+ (IJSVGParser *)groupForFileURL:(NSURL *)aURL
|
||||
{
|
||||
return [[self class] groupForFileURL:aURL
|
||||
return [self.class groupForFileURL:aURL
|
||||
error:nil
|
||||
delegate:nil];
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
+ (IJSVGParser *)groupForFileURL:(NSURL *)aURL
|
||||
delegate:(id<IJSVGParserDelegate>)delegate
|
||||
{
|
||||
return [[self class] groupForFileURL:aURL
|
||||
return [self.class groupForFileURL:aURL
|
||||
error:nil
|
||||
delegate:delegate];
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
error:(NSError **)error
|
||||
delegate:(id<IJSVGParserDelegate>)delegate
|
||||
{
|
||||
return [[[[self class] alloc] initWithFileURL:aURL
|
||||
return [[[self.class alloc] initWithFileURL:aURL
|
||||
error:error
|
||||
delegate:delegate] autorelease];
|
||||
}
|
||||
@@ -947,26 +947,24 @@
|
||||
|
||||
IJSVGLinearGradient * grad = [[[IJSVGLinearGradient alloc] init] autorelease];
|
||||
grad.type = aType;
|
||||
grad.gradient = [IJSVGLinearGradient parseGradient:elementCopy
|
||||
gradient:grad];
|
||||
|
||||
[self _setupDefaultsForNode:grad];
|
||||
[self _parseElementForCommonAttributes:elementCopy
|
||||
node:grad
|
||||
ignoreAttributes:nil];
|
||||
grad.gradient = [IJSVGLinearGradient parseGradient:elementCopy
|
||||
gradient:grad];
|
||||
[parentGroup addDef:grad];
|
||||
break;
|
||||
}
|
||||
|
||||
IJSVGLinearGradient * gradient = [[[IJSVGLinearGradient alloc] init] autorelease];
|
||||
gradient.type = aType;
|
||||
gradient.gradient = [IJSVGLinearGradient parseGradient:element
|
||||
gradient:gradient];
|
||||
|
||||
[self _setupDefaultsForNode:gradient];
|
||||
[self _parseElementForCommonAttributes:element
|
||||
node:gradient
|
||||
ignoreAttributes:nil];
|
||||
gradient.gradient = [IJSVGLinearGradient parseGradient:element
|
||||
gradient:gradient];
|
||||
[parentGroup addDef:gradient];
|
||||
break;
|
||||
}
|
||||
@@ -986,27 +984,24 @@
|
||||
|
||||
NSXMLElement * elementCopy = [self mergedElement:element
|
||||
withReferenceElement:referenceElement];
|
||||
|
||||
grad.gradient = [IJSVGRadialGradient parseGradient:elementCopy
|
||||
gradient:grad];
|
||||
|
||||
[self _setupDefaultsForNode:grad];
|
||||
[self _parseElementForCommonAttributes:elementCopy
|
||||
node:grad
|
||||
ignoreAttributes:nil];
|
||||
grad.gradient = [IJSVGRadialGradient parseGradient:elementCopy
|
||||
gradient:grad];
|
||||
[parentGroup addDef:grad];
|
||||
break;
|
||||
}
|
||||
|
||||
IJSVGRadialGradient * gradient = [[[IJSVGRadialGradient alloc] init] autorelease];
|
||||
gradient.type = aType;
|
||||
gradient.gradient = [IJSVGRadialGradient parseGradient:element
|
||||
gradient:gradient];
|
||||
|
||||
[self _setupDefaultsForNode:gradient];
|
||||
[self _parseElementForCommonAttributes:element
|
||||
node:gradient
|
||||
ignoreAttributes:nil];
|
||||
gradient.gradient = [IJSVGRadialGradient parseGradient:element
|
||||
gradient:gradient];
|
||||
[parentGroup addDef:gradient];
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -50,34 +50,31 @@
|
||||
NSString * str = [element attributeForName:key].stringValue;
|
||||
IJSVGUnitLength * unit = nil;
|
||||
if(str != nil) {
|
||||
unit = [IJSVGUnitLength unitWithString:str];
|
||||
unit = [IJSVGUnitLength unitWithString:str
|
||||
fromUnitType:gradient.units];
|
||||
} else {
|
||||
// spec says to say 50% for missing property default
|
||||
unit = [IJSVGUnitLength unitWithPercentageFloat:.5f];
|
||||
}
|
||||
[gradient setValue:unit
|
||||
forKey:kv[key]];
|
||||
}
|
||||
|
||||
// fx and fy are the same unless specified otherwise
|
||||
gradient.fx = gradient.cx;
|
||||
gradient.fy = gradient.cy;
|
||||
|
||||
// needs fixing
|
||||
NSString * fx = [element attributeForName:@"fx"].stringValue;
|
||||
if(fx != nil) {
|
||||
if(fx.floatValue < 1.f) {
|
||||
gradient.fx = [IJSVGUnitLength unitWithPercentageString:fx];
|
||||
} else {
|
||||
gradient.fx = [IJSVGUnitLength unitWithString:fx];
|
||||
}
|
||||
gradient.fx = [IJSVGUnitLength unitWithString:fx
|
||||
fromUnitType:gradient.units];
|
||||
}
|
||||
|
||||
NSString * fy = [element attributeForName:@"fy"].stringValue;
|
||||
if(fx != nil) {
|
||||
if(fx.floatValue < 1.f) {
|
||||
gradient.fy = [IJSVGUnitLength unitWithPercentageString:fy];
|
||||
} else {
|
||||
gradient.fy = [IJSVGUnitLength unitWithString:fy];
|
||||
}
|
||||
gradient.fy = [IJSVGUnitLength unitWithString:fy
|
||||
fromUnitType:gradient.units];
|
||||
}
|
||||
|
||||
if( gradient.gradient != nil ) {
|
||||
@@ -85,7 +82,7 @@
|
||||
}
|
||||
|
||||
NSArray * colors = nil;
|
||||
CGFloat * colorStops = [[self class] computeColorStopsFromString:element colors:&colors];
|
||||
CGFloat * colorStops = [self.class computeColorStopsFromString:element colors:&colors];
|
||||
NSGradient * ret = [[[NSGradient alloc] initWithColors:colors
|
||||
atLocations:colorStops
|
||||
colorSpace:IJSVGColor.defaultColorSpace] autorelease];
|
||||
@@ -99,7 +96,7 @@
|
||||
viewPort:(CGRect)viewBox
|
||||
{
|
||||
BOOL inUserSpace = self.units == IJSVGUnitUserSpaceOnUse;
|
||||
CGFloat radius = self.radius.value;
|
||||
CGFloat radius = 0.f;
|
||||
CGPoint startPoint = CGPointZero;
|
||||
CGPoint gradientStartPoint = CGPointZero;
|
||||
CGPoint gradientEndPoint = CGPointZero;
|
||||
@@ -107,61 +104,60 @@
|
||||
// transforms
|
||||
CGAffineTransform selfTransform = IJSVGConcatTransforms(self.transforms);
|
||||
|
||||
#pragma mark User Space On Use
|
||||
CGRect boundingBox = inUserSpace ? viewBox : objectRect;
|
||||
|
||||
// make sure we apply the absolute position to
|
||||
// transform us back into the correct space
|
||||
if(inUserSpace == YES) {
|
||||
CGFloat rad = radius*2.f;
|
||||
startPoint = CGPointMake(self.cx.value, self.cy.value);
|
||||
|
||||
// work out the new radius
|
||||
CGRect rect = CGRectMake(startPoint.x, startPoint.y, rad, rad);
|
||||
rect = CGRectApplyAffineTransform(rect, selfTransform);
|
||||
rect = CGRectApplyAffineTransform(rect, absoluteTransform);
|
||||
radius = CGRectGetHeight(rect)/2.f;
|
||||
|
||||
gradientStartPoint = startPoint;
|
||||
gradientEndPoint = CGPointMake(self.fx.value, self.fy.value);
|
||||
|
||||
// apply the absolute position
|
||||
CGContextConcatCTM(ctx, absoluteTransform);
|
||||
} else {
|
||||
#pragma mark Object Bounding Box
|
||||
// compute size based on percentages
|
||||
CGFloat x = [self.cx computeValue:CGRectGetWidth(objectRect)];
|
||||
CGFloat y = [self.cy computeValue:CGRectGetHeight(objectRect)];
|
||||
startPoint = CGPointMake(x, y);
|
||||
CGFloat val = MIN(CGRectGetWidth(objectRect), CGRectGetHeight(objectRect));
|
||||
radius = [self.radius computeValue:val];
|
||||
|
||||
CGFloat ex = [self.fx computeValue:CGRectGetWidth(objectRect)];
|
||||
CGFloat ey = [self.fy computeValue:CGRectGetHeight(objectRect)];
|
||||
|
||||
gradientEndPoint = CGPointMake(ex, ey);
|
||||
gradientStartPoint = startPoint;
|
||||
|
||||
// transform if width or height is not equal
|
||||
if(CGRectGetWidth(objectRect) != CGRectGetHeight(objectRect)) {
|
||||
CGAffineTransform tr = CGAffineTransformMakeTranslation(gradientStartPoint.x,
|
||||
gradientStartPoint.y);
|
||||
if(CGRectGetWidth(objectRect) > CGRectGetHeight(objectRect)) {
|
||||
tr = CGAffineTransformScale(tr, CGRectGetWidth(objectRect)/CGRectGetHeight(objectRect), 1);
|
||||
} else {
|
||||
tr = CGAffineTransformScale(tr, 1.f, CGRectGetHeight(objectRect)/CGRectGetWidth(objectRect));
|
||||
}
|
||||
tr = CGAffineTransformTranslate(tr, -gradientStartPoint.x, -gradientStartPoint.y);
|
||||
selfTransform = CGAffineTransformConcat(tr, selfTransform);
|
||||
}
|
||||
|
||||
|
||||
// compute size based on percentages
|
||||
CGFloat x = [self.cx computeValue:CGRectGetWidth(boundingBox)];
|
||||
CGFloat y = [self.cy computeValue:CGRectGetHeight(boundingBox)];
|
||||
startPoint = CGPointMake(x, y);
|
||||
CGFloat val = MIN(CGRectGetWidth(boundingBox),
|
||||
CGRectGetHeight(boundingBox));
|
||||
radius = [self.radius computeValue:val];
|
||||
|
||||
CGFloat ex = [self.fx computeValue:CGRectGetWidth(boundingBox)];
|
||||
CGFloat ey = [self.fy computeValue:CGRectGetHeight(boundingBox)];
|
||||
|
||||
gradientEndPoint = CGPointMake(ex, ey);
|
||||
gradientStartPoint = startPoint;
|
||||
|
||||
// transform if width or height is not equal - this can only
|
||||
// be done if we are using objectBoundingBox
|
||||
if(inUserSpace == NO && CGRectGetWidth(boundingBox) != CGRectGetHeight(boundingBox)) {
|
||||
CGAffineTransform tr = CGAffineTransformMakeTranslation(gradientStartPoint.x,
|
||||
gradientStartPoint.y);
|
||||
if(CGRectGetWidth(boundingBox) > CGRectGetHeight(boundingBox)) {
|
||||
tr = CGAffineTransformScale(tr, CGRectGetWidth(boundingBox)/CGRectGetHeight(boundingBox), 1);
|
||||
} else {
|
||||
tr = CGAffineTransformScale(tr, 1.f, CGRectGetHeight(boundingBox)/CGRectGetWidth(boundingBox));
|
||||
}
|
||||
tr = CGAffineTransformTranslate(tr, -gradientStartPoint.x, -gradientStartPoint.y);
|
||||
selfTransform = CGAffineTransformConcat(tr, selfTransform);
|
||||
}
|
||||
|
||||
#pragma mark Default drawing
|
||||
// transform the context
|
||||
CGContextConcatCTM(ctx, selfTransform);
|
||||
|
||||
// draw the gradient
|
||||
CGGradientDrawingOptions options = kCGGradientDrawsBeforeStartLocation|
|
||||
CGGradientDrawingOptions options =
|
||||
kCGGradientDrawsBeforeStartLocation|
|
||||
kCGGradientDrawsAfterEndLocation;
|
||||
CGContextDrawRadialGradient(ctx, self.CGGradient,
|
||||
gradientEndPoint, 0, gradientStartPoint,
|
||||
gradientEndPoint, 0,
|
||||
gradientStartPoint,
|
||||
radius, options);
|
||||
|
||||
#ifdef IJSVG_DEBUG_GRADIENTS
|
||||
[self _debugStart:gradientStartPoint
|
||||
end:gradientEndPoint
|
||||
context:ctx];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// IJSVGStyleList.h
|
||||
// IconJar
|
||||
//
|
||||
// Created by Curtis Hard on 09/07/2019.
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "IJSVGNode.h"
|
||||
#import "IJSVGColorList.h"
|
||||
|
||||
@interface IJSVGRenderingStyle : NSObject
|
||||
|
||||
@property (nonatomic, assign) IJSVGLineCapStyle lineCapStyle;
|
||||
@property (nonatomic, assign) IJSVGLineJoinStyle lineJoinStyle;
|
||||
@property (nonatomic, assign) CGFloat lineWidth;
|
||||
@property (nonatomic, retain) IJSVGColorList * colorList;
|
||||
@property (nonatomic, retain) NSColor * fillColor;
|
||||
@property (nonatomic, retain) NSColor * strokeColor;
|
||||
|
||||
+ (NSArray<NSString *> *)observableProperties;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// IJSVGStyleList.m
|
||||
// IconJar
|
||||
//
|
||||
// Created by Curtis Hard on 09/07/2019.
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGRenderingStyle.h"
|
||||
|
||||
@implementation IJSVGRenderingStyle
|
||||
|
||||
@synthesize colorList = _colorList;
|
||||
@synthesize lineCapStyle = _lineCapStyle;
|
||||
@synthesize lineJoinStyle = _lineJoinStyle;
|
||||
@synthesize lineWidth = _lineWidth;
|
||||
@synthesize fillColor = _fillColor;
|
||||
@synthesize strokeColor = _strokeColor;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_fillColor release], _fillColor = nil;
|
||||
[_strokeColor release], _strokeColor = nil;
|
||||
[_colorList release], _colorList = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if((self = [super init]) != nil) {
|
||||
_lineCapStyle = IJSVGLineCapStyleNone;
|
||||
_lineJoinStyle = IJSVGLineJoinStyleNone;
|
||||
_lineWidth = IJSVGInheritedFloatValue;
|
||||
_colorList = [[IJSVGColorList alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (NSArray<NSString *> *)observableProperties
|
||||
{
|
||||
unsigned int count;
|
||||
objc_property_t * properties = class_copyPropertyList(IJSVGRenderingStyle.class,
|
||||
&count);
|
||||
NSMutableArray * names = [[[NSMutableArray alloc] initWithCapacity:count] autorelease];
|
||||
for(int i = 0; i < count; i++) {
|
||||
objc_property_t property = properties[i];
|
||||
const char * name = property_getName(property);
|
||||
NSString * stringName = [NSString stringWithCString:name
|
||||
encoding:NSUTF8StringEncoding];
|
||||
[names addObject:stringName];
|
||||
}
|
||||
free(properties);
|
||||
return names;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// IJSVGStringAdditions.h
|
||||
// IconJar
|
||||
//
|
||||
// Created by Curtis Hard on 07/06/2019.
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NSString (IJSVGAdditions)
|
||||
|
||||
- (NSArray<NSString *> *)componentsSeparatedByChars:(char *)aChar;
|
||||
- (BOOL)isNumeric;
|
||||
- (BOOL)containsAlpha;
|
||||
- (NSArray *)componentsSplitByWhiteSpace;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// IJSVGStringAdditions.m
|
||||
// IconJar
|
||||
//
|
||||
// Created by Curtis Hard on 07/06/2019.
|
||||
// Copyright © 2019 Curtis Hard. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJSVGStringAdditions.h"
|
||||
|
||||
@implementation NSString (IJSVGAdditions)
|
||||
|
||||
- (NSArray<NSString *> *)componentsSeparatedByChars:(char *)aChar
|
||||
{
|
||||
NSMutableArray * comp = [[[NSMutableArray alloc] init] autorelease];
|
||||
NSInteger length = self.length;
|
||||
unichar * chars = (unichar *)calloc(sizeof(unichar),self.length);
|
||||
|
||||
NSInteger ind = 0;
|
||||
BOOL startedString = NO;
|
||||
|
||||
// block for easy comparison
|
||||
NSUInteger aLength = strlen(aChar);
|
||||
BOOL (^charsContainsChar)(char anotherChar) = ^(char anotherChar) {
|
||||
for(NSInteger i = 0; i < aLength; i++) {
|
||||
if(aChar[i] == anotherChar) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
};
|
||||
|
||||
for(NSInteger i = 0; i < length; i++) {
|
||||
|
||||
// the char
|
||||
unichar theChar = [self characterAtIndex:i];
|
||||
|
||||
// start the buffer
|
||||
BOOL isEqualToChar = charsContainsChar(theChar);
|
||||
if(isEqualToChar == NO) {
|
||||
startedString = YES;
|
||||
chars[ind++] = theChar;
|
||||
}
|
||||
|
||||
// has started and char is the search char, or its at end
|
||||
if((startedString == YES && isEqualToChar) ||
|
||||
(i == (length-1) && startedString == YES)) {
|
||||
startedString = NO;
|
||||
|
||||
// append the comp
|
||||
[comp addObject:[NSString stringWithCharacters:chars length:ind]];
|
||||
free(chars);
|
||||
|
||||
// restart and realloc the memory
|
||||
ind = 0;
|
||||
chars = (unichar *)calloc(sizeof(unichar), self.length);
|
||||
}
|
||||
}
|
||||
free(chars);
|
||||
return comp;
|
||||
}
|
||||
|
||||
- (BOOL)containsAlpha
|
||||
{
|
||||
const char * buffer = self.UTF8String;
|
||||
unsigned long length = strlen(buffer);
|
||||
for( int i = 0; i < length; i++ ) {
|
||||
if( isalpha(buffer[i]) ) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isNumeric
|
||||
{
|
||||
const char * buffer = self.UTF8String;
|
||||
unsigned long length = strlen(buffer);
|
||||
for(int i = 0; i < length; i++) {
|
||||
if(!isnumber(buffer[i])) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSArray *)componentsSplitByWhiteSpace
|
||||
{
|
||||
return [self componentsSeparatedByChars:"\t\n\r "];
|
||||
}
|
||||
|
||||
@end
|
||||
+3
-3
@@ -44,7 +44,7 @@
|
||||
|
||||
+ (IJSVGStyle *)parseStyleString:(NSString *)string
|
||||
{
|
||||
IJSVGStyle * style = [[[[self class] alloc] init] autorelease];
|
||||
IJSVGStyle * style = [[[self.class alloc] init] autorelease];
|
||||
NSInteger length = string.length;
|
||||
NSInteger index = 0;
|
||||
NSString * key = nil;
|
||||
@@ -75,8 +75,8 @@
|
||||
|
||||
// set the propery if it actually exists
|
||||
if(key != nil && value != nil) {
|
||||
[style setPropertyValue:[[self class] trimString:value]
|
||||
forProperty:[[self class] trimString:key]];
|
||||
[style setPropertyValue:[self.class trimString:value]
|
||||
forProperty:[self.class trimString:key]];
|
||||
key = nil;
|
||||
value = nil;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ typedef void (^IJSVGTransformApplyBlock)(IJSVGTransform * transform);
|
||||
typedef NS_OPTIONS( NSInteger, IJSVGTransformCommand ) {
|
||||
IJSVGTransformCommandMatrix,
|
||||
IJSVGTransformCommandTranslate,
|
||||
IJSVGTransformCommandTranslateX,
|
||||
IJSVGTransformCommandTranslateY,
|
||||
IJSVGTransformCommandScale,
|
||||
IJSVGTransformCommandRotate,
|
||||
IJSVGTransformCommandSkewX,
|
||||
|
||||
+56
-10
@@ -24,7 +24,7 @@
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
IJSVGTransform * trans = [[[self class] alloc] init];
|
||||
IJSVGTransform * trans = [[self.class alloc] init];
|
||||
trans.command = self.command;
|
||||
trans.parameters = (CGFloat*)malloc(sizeof(CGFloat)*self.parameterCount);
|
||||
trans.sort = sort;
|
||||
@@ -100,6 +100,10 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform *> * transforms, IJSVGTransform
|
||||
return IJSVGTransformCommandMatrix;
|
||||
if( [str isEqualToString:@"translate"] )
|
||||
return IJSVGTransformCommandTranslate;
|
||||
if([str isEqualToString:@"translatex"])
|
||||
return IJSVGTransformCommandTranslateX;
|
||||
if([str isEqualToString:@"translatey"])
|
||||
return IJSVGTransformCommandTranslateY;
|
||||
if( [str isEqualToString:@"scale"] )
|
||||
return IJSVGTransformCommandScale;
|
||||
if( [str isEqualToString:@"skewx"])
|
||||
@@ -120,6 +124,8 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform *> * transforms, IJSVGTransform
|
||||
return 1;
|
||||
case IJSVGTransformCommandMatrix:
|
||||
return 2;
|
||||
case IJSVGTransformCommandTranslateX:
|
||||
case IJSVGTransformCommandTranslateY:
|
||||
case IJSVGTransformCommandTranslate:
|
||||
return -1;
|
||||
default:
|
||||
@@ -133,7 +139,7 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform *> * transforms, IJSVGTransform
|
||||
static NSRegularExpression * _reg = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_reg = [[NSRegularExpression alloc] initWithPattern:@"([a-zA-Z]+)\\((.*?)\\)"
|
||||
_reg = [[NSRegularExpression alloc] initWithPattern:@"([a-zA-Z]+)\\(([^\\)]+)\\)"
|
||||
options:0
|
||||
error:nil];
|
||||
});
|
||||
@@ -142,23 +148,23 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform *> * transforms, IJSVGTransform
|
||||
[_reg enumerateMatchesInString:string
|
||||
options:0
|
||||
range:NSMakeRange( 0, string.length )
|
||||
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
|
||||
{
|
||||
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
|
||||
NSString * command = [string substringWithRange:[result rangeAtIndex:1]];
|
||||
IJSVGTransformCommand commandType = [[self class] commandForCommandString:command];
|
||||
IJSVGTransformCommand commandType = [self.class commandForCommandString:command];
|
||||
if( commandType == IJSVGTransformCommandNotImplemented ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// create the transform
|
||||
NSString * params = [string substringWithRange:[result rangeAtIndex:2]];
|
||||
IJSVGTransform * transform = [[[[self class] alloc] init] autorelease];
|
||||
IJSVGTransform * transform = [[[self.class alloc] init] autorelease];
|
||||
NSInteger count = 0;
|
||||
transform.command = commandType;
|
||||
transform.parameters = [IJSVGUtils commandParameters:params
|
||||
count:&count];
|
||||
transform.parameterCount = count;
|
||||
transform.sort = [[self class] sortForTransformCommand:commandType];
|
||||
transform.sort = [self.class sortForTransformCommand:commandType];
|
||||
[transforms addObject:transform];
|
||||
}];
|
||||
}
|
||||
@@ -228,6 +234,18 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform *> * transforms, IJSVGTransform
|
||||
yBy:transform.parameters[1]];
|
||||
break;
|
||||
}
|
||||
|
||||
// translateX
|
||||
case IJSVGTransformCommandTranslateX: {
|
||||
[at translateXBy:transform.parameters[0] yBy:0.f];
|
||||
break;
|
||||
}
|
||||
|
||||
// translateY
|
||||
case IJSVGTransformCommandTranslateY: {
|
||||
[at translateXBy:0.f yBy:transform.parameters[0]];
|
||||
break;
|
||||
}
|
||||
|
||||
// scale
|
||||
case IJSVGTransformCommandScale: {
|
||||
@@ -283,6 +301,16 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform *> * transforms, IJSVGTransform
|
||||
}
|
||||
return CGAffineTransformTranslate(identity, self.parameters[0], self.parameters[1]);
|
||||
}
|
||||
|
||||
// translateX
|
||||
case IJSVGTransformCommandTranslateX: {
|
||||
return CGAffineTransformTranslate(identity, self.parameters[0], 0.f);
|
||||
}
|
||||
|
||||
// translateY
|
||||
case IJSVGTransformCommandTranslateY: {
|
||||
return CGAffineTransformTranslate(identity, 0.f, self.parameters[0]);
|
||||
}
|
||||
|
||||
// rotate
|
||||
case IJSVGTransformCommandRotate: {
|
||||
@@ -359,9 +387,9 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform *> * transforms, IJSVGTransform
|
||||
p0 = modifier(0,p0);
|
||||
p1 = modifier(1,p1);
|
||||
p2 = modifier(2,p2);
|
||||
p3 = modifier(2,p3);
|
||||
p4 = modifier(2,p4);
|
||||
p5 = modifier(2,p5);
|
||||
p3 = modifier(3,p3);
|
||||
p4 = modifier(4,p4);
|
||||
p5 = modifier(5,p5);
|
||||
}
|
||||
return CGAffineTransformMake(p0, p1, p2, p3, p4, p5);
|
||||
}
|
||||
@@ -380,6 +408,24 @@ void IJSVGApplyTransform(NSArray<IJSVGTransform *> * transforms, IJSVGTransform
|
||||
return CGAffineTransformMakeTranslation(p0, p1);
|
||||
}
|
||||
|
||||
// translateX
|
||||
case IJSVGTransformCommandTranslateX: {
|
||||
CGFloat p0 = self.parameters[0];
|
||||
if(modifier != nil) {
|
||||
p0 = modifier(0, p0);
|
||||
}
|
||||
return CGAffineTransformMakeTranslation(p0, 0.f);
|
||||
}
|
||||
|
||||
// translateY
|
||||
case IJSVGTransformCommandTranslateY: {
|
||||
CGFloat p0 = self.parameters[0];
|
||||
if(modifier != nil) {
|
||||
p0 = modifier(0, p0);
|
||||
}
|
||||
return CGAffineTransformMakeTranslation(0.f, p0);
|
||||
}
|
||||
|
||||
// scale
|
||||
case IJSVGTransformCommandScale: {
|
||||
CGFloat p0 = self.parameters[0];
|
||||
|
||||
@@ -13,6 +13,12 @@ typedef NS_ENUM(NSInteger, IJSVGUnitLengthType) {
|
||||
IJSVGUnitLengthTypePercentage
|
||||
};
|
||||
|
||||
typedef NS_ENUM( NSInteger, IJSVGUnitType) {
|
||||
IJSVGUnitUserSpaceOnUse,
|
||||
IJSVGUnitObjectBoundingBox,
|
||||
IJSVGUnitInherit
|
||||
};
|
||||
|
||||
@interface IJSVGUnitLength : NSObject
|
||||
|
||||
@property (nonatomic, assign) IJSVGUnitLengthType type;
|
||||
@@ -26,6 +32,9 @@ typedef NS_ENUM(NSInteger, IJSVGUnitLengthType) {
|
||||
+ (IJSVGUnitLength *)unitWithString:(NSString *)string;
|
||||
+ (IJSVGUnitLength *)unitWithPercentageString:(NSString *)string;
|
||||
|
||||
+ (IJSVGUnitLength *)unitWithString:(NSString *)string
|
||||
fromUnitType:(IJSVGUnitType)units;
|
||||
|
||||
- (CGFloat)valueAsPercentage;
|
||||
- (CGFloat)computeValue:(CGFloat)anotherValue;
|
||||
- (NSString *)stringValue;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
#import "IJSVGUnitLength.h"
|
||||
#import "IJSVGNode.h"
|
||||
|
||||
@implementation IJSVGUnitLength
|
||||
|
||||
@@ -22,6 +23,15 @@
|
||||
return unit;
|
||||
}
|
||||
|
||||
+ (IJSVGUnitLength *)unitWithString:(NSString *)string
|
||||
fromUnitType:(IJSVGUnitType)units
|
||||
{
|
||||
if(units == IJSVGUnitObjectBoundingBox) {
|
||||
return [self unitWithPercentageString:string];
|
||||
}
|
||||
return [self unitWithString:string];
|
||||
}
|
||||
|
||||
+ (IJSVGUnitLength *)unitWithFloat:(CGFloat)number
|
||||
type:(IJSVGUnitLengthType)type
|
||||
{
|
||||
@@ -47,13 +57,16 @@
|
||||
+ (IJSVGUnitLength *)unitWithString:(NSString *)string
|
||||
{
|
||||
// just return noting for inherit, node will deal
|
||||
// with the rest
|
||||
// with the rest...hopefully
|
||||
NSCharacterSet * cSet = NSCharacterSet.whitespaceCharacterSet;
|
||||
string = [string stringByTrimmingCharactersInSet:cSet];
|
||||
|
||||
if([string isEqualToString:@"inherit"]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
IJSVGUnitLength * unit = [[[self alloc] init] autorelease];
|
||||
unit.value = [string floatValue];
|
||||
unit.value = string.floatValue;
|
||||
unit.type = IJSVGUnitLengthTypeNumber;
|
||||
if([string hasSuffix:@"%"] == YES) {
|
||||
unit.value /= 100.f;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <xlocale.h>
|
||||
#import "IJSVGCommand.h"
|
||||
#import "IJSVGGradientUnitLength.h"
|
||||
#import "IJSVGStringAdditions.h"
|
||||
|
||||
@interface IJSVGUtils : NSObject
|
||||
|
||||
@@ -37,6 +38,7 @@ BOOL IJSVGIsSVGLayer(CALayer * layer);
|
||||
+ (IJSVGUnitType)unitTypeForString:(NSString *)string;
|
||||
+ (IJSVGBlendMode)blendModeForString:(NSString *)string;
|
||||
+ (NSString *)mixBlendingModeForBlendMode:(IJSVGBlendMode)blendMode;
|
||||
+ (NSRange)rangeOfParentheses:(NSString *)string;
|
||||
|
||||
+ (void)logParameters:(CGFloat *)param
|
||||
count:(NSInteger)count;
|
||||
|
||||
+34
-6
@@ -217,12 +217,36 @@ CGFloat degrees_to_radians( CGFloat degrees )
|
||||
return isupper([string characterAtIndex:0]) ? IJSVGCommandTypeAbsolute : IJSVGCommandTypeRelative;
|
||||
}
|
||||
|
||||
+ (NSRange)rangeOfParentheses:(NSString *)string
|
||||
{
|
||||
NSRange range = NSMakeRange(NSNotFound, 0);
|
||||
const char * characters = string.UTF8String;
|
||||
unsigned long length = strlen(characters);
|
||||
for(NSInteger i = 0; i < length; i++) {
|
||||
char c = characters[i];
|
||||
if(c == '(') {
|
||||
range.location = i + 1;
|
||||
} else if(c == ')') {
|
||||
range.length = i - range.location;
|
||||
}
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
+ (NSString *)defURL:(NSString *)string
|
||||
{
|
||||
// insta check for URL
|
||||
NSCharacterSet * set = NSCharacterSet.whitespaceCharacterSet;
|
||||
string = [string stringByTrimmingCharactersInSet:set];
|
||||
NSString * check = [string substringToIndex:3].lowercaseString;
|
||||
if([check isEqualToString:@"url"] == NO) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
static NSRegularExpression * _reg = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_reg = [[NSRegularExpression alloc] initWithPattern:@"url\\s?\\(\\s?#(.*?)\\)\\;?"
|
||||
_reg = [[NSRegularExpression alloc] initWithPattern:@"url\\(['\"]?([^)]+?)['\"]?\\)"
|
||||
options:0
|
||||
error:nil];
|
||||
});
|
||||
@@ -230,11 +254,15 @@ CGFloat degrees_to_radians( CGFloat degrees )
|
||||
[_reg enumerateMatchesInString:string
|
||||
options:0
|
||||
range:NSMakeRange( 0, string.length )
|
||||
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
|
||||
{
|
||||
if( ( foundID = [string substringWithRange:[result rangeAtIndex:1]] ) != nil )
|
||||
usingBlock:^(NSTextCheckingResult *result,
|
||||
NSMatchingFlags flags, BOOL *stop) {
|
||||
if((foundID = [string substringWithRange:[result rangeAtIndex:1]]) != nil) {
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
if([foundID hasPrefix:@"#"] == YES) {
|
||||
foundID = [foundID substringFromIndex:1];
|
||||
}
|
||||
return foundID;
|
||||
}
|
||||
|
||||
@@ -399,7 +427,7 @@ CGFloat degrees_to_radians( CGFloat degrees )
|
||||
*count = 1;
|
||||
return ret;
|
||||
}
|
||||
return [[self class] scanFloatsFromString:command
|
||||
return [self.class scanFloatsFromString:command
|
||||
size:count];
|
||||
}
|
||||
|
||||
@@ -503,7 +531,7 @@ CGFloat degrees_to_radians( CGFloat degrees )
|
||||
+ (CGFloat *)parseViewBox:(NSString *)string
|
||||
{
|
||||
NSInteger size = 0;
|
||||
return [[self class] scanFloatsFromString:string
|
||||
return [self.class scanFloatsFromString:string
|
||||
size:&size];
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@
|
||||
if(imageName != nil) {
|
||||
IJSVG * anSVG = [IJSVG svgNamed:imageName];
|
||||
if(tintColor != nil) {
|
||||
anSVG.fillColor = tintColor;
|
||||
anSVG.style.fillColor = tintColor;
|
||||
}
|
||||
self.SVG = anSVG;
|
||||
}
|
||||
|
||||
@@ -18,17 +18,17 @@
|
||||
[trans scaleXBy:1.f yBy:-1.f];
|
||||
[trans translateXBy:0.f yBy:path.controlPointBounds.size.height];
|
||||
path = [trans transformBezierPath:path];
|
||||
return [[self class] SVGDocumentStringForBezierPath:path];
|
||||
return [self.class SVGDocumentStringForBezierPath:path];
|
||||
}
|
||||
|
||||
+ (NSString *)SVGDocumentStringForBezierPath:(NSBezierPath *)path
|
||||
{
|
||||
return [[self class] SVGDocumentForBezierPath:path].XMLString;
|
||||
return [self.class SVGDocumentForBezierPath:path].XMLString;
|
||||
}
|
||||
|
||||
+ (NSXMLDocument *)SVGDocumentForBezierPath:(NSBezierPath *)path
|
||||
{
|
||||
NSXMLElement * root = [[self class] rootElementForPath:path];
|
||||
NSXMLElement * root = [self.class rootElementForPath:path];
|
||||
|
||||
// create the path data
|
||||
NSXMLElement * p = [[[NSXMLElement alloc] initWithName:@"path"] autorelease];
|
||||
@@ -36,7 +36,7 @@
|
||||
// add the drawing command
|
||||
NSXMLNode * n = [[[NSXMLNode alloc] initWithKind:NSXMLAttributeKind] autorelease];
|
||||
[n setName:@"d"];
|
||||
[n setStringValue:[[self class] SVGPathStringForBezierPath:path]];
|
||||
[n setStringValue:[self.class SVGPathStringForBezierPath:path]];
|
||||
[p addAttribute:n];
|
||||
|
||||
// add the drawing path to the root
|
||||
|
||||
Reference in New Issue
Block a user