Compare commits

..

29 Commits

Author SHA1 Message Date
Curtis Hard 8f84aa9070 Modern syntax 2019-08-15 13:16:20 +01:00
Curtis Hard 200fd6893d Fixes memory leak 2019-08-14 23:04:01 +01:00
Curtis Hard 01ad4eaeb2 Fixes clipping issue when drawing into a context 2019-07-21 22:17:58 +01:00
Curtis Hard 6b1c988d89 Added shorthand function for chcking export types 2019-07-17 22:31:13 +01:00
Curtis Hard c91ac95bc2 Swaps over normal attribute setting to a rendering style object instead 2019-07-14 15:35:40 +01:00
Curtis Hard cf14f27560 More color list features 2019-07-07 21:01:38 +01:00
Curtis Hard cef1de35d7 Inital colour sstuff 2019-07-07 20:26:39 +01:00
Curtis Hard c1a98ef5a6 Update all things! 2019-07-07 11:27:20 +01:00
Curtis Hard 690e1c8619 visibleColors now also returns if it has patternFills 2019-07-06 16:55:07 +01:00
Curtis Hard eda2b73eb2 More fixes for gradients 2019-07-06 15:52:41 +01:00
Curtis Hard f00ede11f0 More gradient fixes 2019-07-06 15:31:17 +01:00
Curtis Hard 169da55131 More fixes 2019-07-05 22:34:05 +01:00
Curtis Hard acfec29765 Fixes project for latest master 2019-07-05 15:18:14 +01:00
Curtis Hard a44cc7c098 Fixes objectBoundBox values 2019-07-05 15:16:56 +01:00
Curtis Hard 171e97451b Initial fixes for userSpaceOnUse 2019-07-05 13:27:18 +01:00
Curtis Hard 27e096350e Fixes issue with RGB being parsed incorrectly 2019-07-04 10:04:27 +01:00
Curtis Hard 04646fe4ec Fixes color bug with predefined colours 2019-07-03 21:06:58 +01:00
Curtis Hard a092b612a8 Added translateX and translateY to available transforms
- also fixes more gradient issues
2019-07-03 20:59:47 +01:00
Curtis Hard d176fe6396 This fixes userSpaceOnUse issues with gradients (i think and hope - fingers crossed) 2019-07-03 18:29:12 +01:00
Curtis Hard c94de1d241 Fixes URL parsing and scaling for gradients 2019-07-02 22:27:51 +01:00
Curtis Hard 1294372daa Moved [self class] over to modern syntax 2019-06-22 16:24:32 +01:00
Curtis Hard 60e5c6b68a Slight refactor 2019-06-16 14:00:47 +01:00
Curtis Hard 06c8191732 Added image by maintaining aspect ratio 2019-06-16 12:56:36 +01:00
Curtis Hard 2f0bead7a4 Sets initial stroke width to 1.0, should not be 0.f! 2019-06-10 15:10:52 +01:00
Curtis Hard ee46609165 Merge branch 'master' of https://github.com/IconJar/IJSVG 2019-06-07 10:04:50 +01:00
Curtis Hard 9e58ae6e19 Added string additions 2019-06-07 10:04:47 +01:00
Curtis Hard 199d1a5707 This fixes issue with strokes being set to 0 and not being interpreted correctly 2019-05-22 18:14:29 +01:00
Curtis Hard f72ae8b401 RGB values now support percentage values 2019-05-13 15:58:36 +01:00
Curtis Hard c126f511d6 Merge branch 'features/performance-increases' 2019-03-27 08:25:47 +00:00
48 changed files with 4034 additions and 424 deletions
@@ -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 */,
@@ -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>
@@ -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>
+2 -2
View File
@@ -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

+32
View File
@@ -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

+12
View File
@@ -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

+5 -19
View File
@@ -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

+30
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+4
View File
@@ -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
View File
@@ -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
+31
View File
@@ -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
+113
View File
@@ -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
+2 -2
View File
@@ -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:&parameterCount];
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);
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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] )
{
+2
View File
@@ -43,6 +43,8 @@ typedef NS_OPTIONS( NSInteger, IJSVGExporterOptions) {
IJSVGExporterOptionRemoveWidthHeightAttributes
};
BOOL IJSVGExporterHasOption(IJSVGExporterOptions options, NSInteger option);
@interface IJSVGExporter : NSObject {
@private
+10
View File
@@ -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";
+8
View File
@@ -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
View File
@@ -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
+2 -2
View File
@@ -65,11 +65,11 @@
{
switch (self.renderQuality) {
case IJSVGRenderQualityOptimized: {
backingScaleFactor = .35f;
backingScaleFactor = (backingScaleFactor * .35f);
break;
}
case IJSVGRenderQualityLow: {
backingScaleFactor = .05f;
backingScaleFactor = (backingScaleFactor * .05f);
break;
}
default: {
+1 -1
View File
@@ -44,7 +44,7 @@
+ (instancetype)imageRepWithData:(NSData *)data
{
return [[self alloc] initWithData:data];
return [[[self alloc] initWithData:data] autorelease];
}
- (void)dealloc
+3 -6
View File
@@ -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
View File
@@ -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;
+31 -51
View File
@@ -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
-6
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+52 -56
View File
@@ -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
+24
View File
@@ -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
+56
View File
@@ -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
+18
View File
@@ -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
+92
View File
@@ -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
View File
@@ -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;
}
+2
View File
@@ -17,6 +17,8 @@ typedef void (^IJSVGTransformApplyBlock)(IJSVGTransform * transform);
typedef NS_OPTIONS( NSInteger, IJSVGTransformCommand ) {
IJSVGTransformCommandMatrix,
IJSVGTransformCommandTranslate,
IJSVGTransformCommandTranslateX,
IJSVGTransformCommandTranslateY,
IJSVGTransformCommandScale,
IJSVGTransformCommandRotate,
IJSVGTransformCommandSkewX,
+56 -10
View File
@@ -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];
+9
View File
@@ -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;
+15 -2
View File
@@ -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;
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+4 -4
View File
@@ -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