Merge branch 'master1' into swift_4.1
@ -253,11 +253,32 @@
|
||||
57F1087C1F53CA7E00DC365B /* MDisplayLink_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57F1087B1F53CA7E00DC365B /* MDisplayLink_iOS.swift */; };
|
||||
57FCD2771D76EA4600CC0FB6 /* Macaw.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 57FCD26C1D76EA4600CC0FB6 /* Macaw.framework */; };
|
||||
57FCD27C1D76EA4600CC0FB6 /* MacawTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57FCD27B1D76EA4600CC0FB6 /* MacawTests.swift */; };
|
||||
602C561D2081C984003AD452 /* rounded.svg in Resources */ = {isa = PBXBuildFile; fileRef = 602C561C2081C984003AD452 /* rounded.svg */; };
|
||||
5B1FFD7A207E083600716A46 /* SvgContentLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BAA56A7207C73FF0055BC5B /* SvgContentLayout.swift */; };
|
||||
5BAA56A8207C73FF0055BC5B /* SvgContentLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BAA56A7207C73FF0055BC5B /* SvgContentLayout.swift */; };
|
||||
5BAE201F208E1211006BF277 /* SVGCanvas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BAE201E208E1211006BF277 /* SVGCanvas.swift */; };
|
||||
5BAE2038208E163D006BF277 /* polyline.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2022208E1637006BF277 /* polyline.reference */; };
|
||||
5BAE2039208E163D006BF277 /* polygon.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2023208E1637006BF277 /* polygon.reference */; };
|
||||
5BAE203A208E163D006BF277 /* rect.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2024208E1637006BF277 /* rect.reference */; };
|
||||
5BAE203C208E163D006BF277 /* triangle.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2026208E1637006BF277 /* triangle.reference */; };
|
||||
5BAE203D208E163D006BF277 /* clipManual.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2027208E1637006BF277 /* clipManual.reference */; };
|
||||
5BAE203E208E163D006BF277 /* circle.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2028208E1637006BF277 /* circle.reference */; };
|
||||
5BAE203F208E163D006BF277 /* transform.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2029208E1638006BF277 /* transform.reference */; };
|
||||
5BAE2040208E163D006BF277 /* ellipse.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE202A208E1638006BF277 /* ellipse.reference */; };
|
||||
5BAE2042208E163D006BF277 /* group.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE202C208E1638006BF277 /* group.reference */; };
|
||||
5BAE2043208E163D006BF277 /* textBasicTransform.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE202D208E1638006BF277 /* textBasicTransform.reference */; };
|
||||
5BAE2044208E163D006BF277 /* style.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE202E208E1639006BF277 /* style.reference */; };
|
||||
5BAE2045208E163D006BF277 /* arcsgroup.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE202F208E163A006BF277 /* arcsgroup.reference */; };
|
||||
5BAE2047208E163D006BF277 /* viewBox.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2031208E163B006BF277 /* viewBox.reference */; };
|
||||
5BAE2048208E163D006BF277 /* line.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2032208E163B006BF277 /* line.reference */; };
|
||||
5BAE204A208E163D006BF277 /* roundRect.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2034208E163B006BF277 /* roundRect.reference */; };
|
||||
5BAE204B208E163D006BF277 /* clip.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2035208E163C006BF277 /* clip.reference */; };
|
||||
5BAE204C208E1EF4006BF277 /* SVGCanvas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BAE201E208E1211006BF277 /* SVGCanvas.swift */; };
|
||||
5BAE2058208F24DE006BF277 /* SceneSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BAE2057208F24DE006BF277 /* SceneSerialization.swift */; };
|
||||
5BAE2061208F2504006BF277 /* color-prop-02-f-manual.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE205B208F2504006BF277 /* color-prop-02-f-manual.svg */; };
|
||||
5BAE2062208F2504006BF277 /* shapes-circle-01-t-manual.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE205C208F2504006BF277 /* shapes-circle-01-t-manual.svg */; };
|
||||
5BAE2063208F2504006BF277 /* shapes-circle-01-t-manual.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE205D208F2504006BF277 /* shapes-circle-01-t-manual.reference */; };
|
||||
5BAE2066208F2504006BF277 /* color-prop-02-f-manual.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2060208F2504006BF277 /* color-prop-02-f-manual.reference */; };
|
||||
5BAEA9C9206CEAA20049AAAE /* viewBox.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5BAEA9C8206CEAA20049AAAE /* viewBox.svg */; };
|
||||
5BAEA9CB206CEB7D0049AAAE /* viewBox.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAEA9CA206CEB7D0049AAAE /* viewBox.reference */; };
|
||||
A718CD441F45C28200966E06 /* Common_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A718CD431F45C28200966E06 /* Common_iOS.swift */; };
|
||||
A718CD471F45C28700966E06 /* Graphics_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A718CD451F45C28700966E06 /* Graphics_iOS.swift */; };
|
||||
A718CD481F45C28700966E06 /* MView_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A718CD461F45C28700966E06 /* MView_iOS.swift */; };
|
||||
@ -271,13 +292,6 @@
|
||||
C4153A8F1F8793DE001BA5EE /* small-logo.png in Resources */ = {isa = PBXBuildFile; fileRef = C4153A8E1F8793DD001BA5EE /* small-logo.png */; };
|
||||
C43B064D1F9738EF00787A35 /* clip.svg in Resources */ = {isa = PBXBuildFile; fileRef = C43B064C1F9738EF00787A35 /* clip.svg */; };
|
||||
C43B06511F9866E400787A35 /* Locus+ToPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43B06501F9866E400787A35 /* Locus+ToPath.swift */; };
|
||||
C43B06531F989D9300787A35 /* transform.reference in Resources */ = {isa = PBXBuildFile; fileRef = C43B06521F989D9300787A35 /* transform.reference */; };
|
||||
C43B06551F98A53600787A35 /* group.reference in Resources */ = {isa = PBXBuildFile; fileRef = C43B06541F98A53600787A35 /* group.reference */; };
|
||||
C43B06571F98A7B700787A35 /* arcsgroup.reference in Resources */ = {isa = PBXBuildFile; fileRef = C43B06561F98A7B700787A35 /* arcsgroup.reference */; };
|
||||
C43B06591F98A84200787A35 /* style.reference in Resources */ = {isa = PBXBuildFile; fileRef = C43B06581F98A84200787A35 /* style.reference */; };
|
||||
C43B065B1F98A9E000787A35 /* clipManual.reference in Resources */ = {isa = PBXBuildFile; fileRef = C43B065A1F98A9E000787A35 /* clipManual.reference */; };
|
||||
C43B065F1F98AAA500787A35 /* clip.reference in Resources */ = {isa = PBXBuildFile; fileRef = C43B065E1F98AAA500787A35 /* clip.reference */; };
|
||||
C43B06611F98ACFC00787A35 /* textBasicTransform.reference in Resources */ = {isa = PBXBuildFile; fileRef = C43B06601F98ACFC00787A35 /* textBasicTransform.reference */; };
|
||||
C43B06631F99A33400787A35 /* pathbounds3.svg in Resources */ = {isa = PBXBuildFile; fileRef = C43B06621F99A33400787A35 /* pathbounds3.svg */; };
|
||||
C43B06661F99EE7300787A35 /* cubicAbsolute.svg in Resources */ = {isa = PBXBuildFile; fileRef = C43B06641F99EE7200787A35 /* cubicAbsolute.svg */; };
|
||||
C43B06671F99EE7300787A35 /* cubicRelative.svg in Resources */ = {isa = PBXBuildFile; fileRef = C43B06651F99EE7300787A35 /* cubicRelative.svg */; };
|
||||
@ -454,10 +468,30 @@
|
||||
57FCD2761D76EA4600CC0FB6 /* MacawTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MacawTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
57FCD27B1D76EA4600CC0FB6 /* MacawTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacawTests.swift; sourceTree = "<group>"; };
|
||||
57FCD27D1D76EA4600CC0FB6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
602C561C2081C984003AD452 /* rounded.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = rounded.svg; sourceTree = "<group>"; };
|
||||
5BAA56A7207C73FF0055BC5B /* SvgContentLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SvgContentLayout.swift; sourceTree = "<group>"; };
|
||||
5BAE201E208E1211006BF277 /* SVGCanvas.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SVGCanvas.swift; sourceTree = "<group>"; };
|
||||
5BAE2022208E1637006BF277 /* polyline.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = polyline.reference; sourceTree = "<group>"; };
|
||||
5BAE2023208E1637006BF277 /* polygon.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = polygon.reference; sourceTree = "<group>"; };
|
||||
5BAE2024208E1637006BF277 /* rect.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rect.reference; sourceTree = "<group>"; };
|
||||
5BAE2026208E1637006BF277 /* triangle.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = triangle.reference; sourceTree = "<group>"; };
|
||||
5BAE2027208E1637006BF277 /* clipManual.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = clipManual.reference; sourceTree = "<group>"; };
|
||||
5BAE2028208E1637006BF277 /* circle.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = circle.reference; sourceTree = "<group>"; };
|
||||
5BAE2029208E1638006BF277 /* transform.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = transform.reference; sourceTree = "<group>"; };
|
||||
5BAE202A208E1638006BF277 /* ellipse.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ellipse.reference; sourceTree = "<group>"; };
|
||||
5BAE202C208E1638006BF277 /* group.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = group.reference; sourceTree = "<group>"; };
|
||||
5BAE202D208E1638006BF277 /* textBasicTransform.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = textBasicTransform.reference; sourceTree = "<group>"; };
|
||||
5BAE202E208E1639006BF277 /* style.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = style.reference; sourceTree = "<group>"; };
|
||||
5BAE202F208E163A006BF277 /* arcsgroup.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = arcsgroup.reference; sourceTree = "<group>"; };
|
||||
5BAE2031208E163B006BF277 /* viewBox.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = viewBox.reference; sourceTree = "<group>"; };
|
||||
5BAE2032208E163B006BF277 /* line.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = line.reference; sourceTree = "<group>"; };
|
||||
5BAE2034208E163B006BF277 /* roundRect.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = roundRect.reference; sourceTree = "<group>"; };
|
||||
5BAE2035208E163C006BF277 /* clip.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = clip.reference; sourceTree = "<group>"; };
|
||||
5BAE2057208F24DE006BF277 /* SceneSerialization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneSerialization.swift; sourceTree = "<group>"; };
|
||||
5BAE205B208F2504006BF277 /* color-prop-02-f-manual.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "color-prop-02-f-manual.svg"; sourceTree = "<group>"; };
|
||||
5BAE205C208F2504006BF277 /* shapes-circle-01-t-manual.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "shapes-circle-01-t-manual.svg"; sourceTree = "<group>"; };
|
||||
5BAE205D208F2504006BF277 /* shapes-circle-01-t-manual.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "shapes-circle-01-t-manual.reference"; sourceTree = "<group>"; };
|
||||
5BAE2060208F2504006BF277 /* color-prop-02-f-manual.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "color-prop-02-f-manual.reference"; sourceTree = "<group>"; };
|
||||
5BAEA9C8206CEAA20049AAAE /* viewBox.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = viewBox.svg; sourceTree = "<group>"; };
|
||||
5BAEA9CA206CEB7D0049AAAE /* viewBox.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = viewBox.reference; sourceTree = "<group>"; };
|
||||
A718CD431F45C28200966E06 /* Common_iOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Common_iOS.swift; path = Source/platform/iOS/Common_iOS.swift; sourceTree = SOURCE_ROOT; };
|
||||
A718CD451F45C28700966E06 /* Graphics_iOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Graphics_iOS.swift; path = Source/platform/iOS/Graphics_iOS.swift; sourceTree = SOURCE_ROOT; };
|
||||
A718CD461F45C28700966E06 /* MView_iOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MView_iOS.swift; path = Source/platform/iOS/MView_iOS.swift; sourceTree = SOURCE_ROOT; };
|
||||
@ -471,13 +505,6 @@
|
||||
C4153A8E1F8793DD001BA5EE /* small-logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "small-logo.png"; sourceTree = "<group>"; };
|
||||
C43B064C1F9738EF00787A35 /* clip.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = clip.svg; sourceTree = "<group>"; };
|
||||
C43B06501F9866E400787A35 /* Locus+ToPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Locus+ToPath.swift"; sourceTree = "<group>"; };
|
||||
C43B06521F989D9300787A35 /* transform.reference */ = {isa = PBXFileReference; lastKnownFileType = text; path = transform.reference; sourceTree = "<group>"; };
|
||||
C43B06541F98A53600787A35 /* group.reference */ = {isa = PBXFileReference; lastKnownFileType = text; path = group.reference; sourceTree = "<group>"; };
|
||||
C43B06561F98A7B700787A35 /* arcsgroup.reference */ = {isa = PBXFileReference; lastKnownFileType = text; path = arcsgroup.reference; sourceTree = "<group>"; };
|
||||
C43B06581F98A84200787A35 /* style.reference */ = {isa = PBXFileReference; lastKnownFileType = text; path = style.reference; sourceTree = "<group>"; };
|
||||
C43B065A1F98A9E000787A35 /* clipManual.reference */ = {isa = PBXFileReference; lastKnownFileType = text; path = clipManual.reference; sourceTree = "<group>"; };
|
||||
C43B065E1F98AAA500787A35 /* clip.reference */ = {isa = PBXFileReference; lastKnownFileType = text; path = clip.reference; sourceTree = "<group>"; };
|
||||
C43B06601F98ACFC00787A35 /* textBasicTransform.reference */ = {isa = PBXFileReference; lastKnownFileType = text; path = textBasicTransform.reference; sourceTree = "<group>"; };
|
||||
C43B06621F99A33400787A35 /* pathbounds3.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = pathbounds3.svg; path = Bounds/pathbounds3.svg; sourceTree = "<group>"; };
|
||||
C43B06641F99EE7200787A35 /* cubicAbsolute.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = cubicAbsolute.svg; path = Bounds/cubicAbsolute.svg; sourceTree = "<group>"; };
|
||||
C43B06651F99EE7300787A35 /* cubicRelative.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = cubicRelative.svg; path = Bounds/cubicRelative.svg; sourceTree = "<group>"; };
|
||||
@ -565,29 +592,36 @@
|
||||
57CAB1241D7832E000FD8E47 /* svg */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
602C561C2081C984003AD452 /* rounded.svg */,
|
||||
5BAEA9C8206CEAA20049AAAE /* viewBox.svg */,
|
||||
C46E83541F94B20E00208037 /* transform.svg */,
|
||||
C43B064C1F9738EF00787A35 /* clip.svg */,
|
||||
C4153A8E1F8793DD001BA5EE /* small-logo.png */,
|
||||
C410148D1F834D280022EE44 /* style.svg */,
|
||||
5BAE202F208E163A006BF277 /* arcsgroup.reference */,
|
||||
5BAE2028208E1637006BF277 /* circle.reference */,
|
||||
57CAB1251D7832E000FD8E47 /* circle.svg */,
|
||||
5BAE2035208E163C006BF277 /* clip.reference */,
|
||||
C43B064C1F9738EF00787A35 /* clip.svg */,
|
||||
5BAE2027208E1637006BF277 /* clipManual.reference */,
|
||||
5BAE202A208E1638006BF277 /* ellipse.reference */,
|
||||
57CAB1261D7832E000FD8E47 /* ellipse.svg */,
|
||||
5BAE202C208E1638006BF277 /* group.reference */,
|
||||
57CAB1271D7832E000FD8E47 /* group.svg */,
|
||||
5BAE2032208E163B006BF277 /* line.reference */,
|
||||
57CAB1281D7832E000FD8E47 /* line.svg */,
|
||||
5BAE2023208E1637006BF277 /* polygon.reference */,
|
||||
57CAB1291D7832E000FD8E47 /* polygon.svg */,
|
||||
5BAE2022208E1637006BF277 /* polyline.reference */,
|
||||
57CAB12A1D7832E000FD8E47 /* polyline.svg */,
|
||||
5BAE2024208E1637006BF277 /* rect.reference */,
|
||||
57CAB12B1D7832E000FD8E47 /* rect.svg */,
|
||||
5BAE2034208E163B006BF277 /* roundRect.reference */,
|
||||
57CAB12C1D7832E000FD8E47 /* roundRect.svg */,
|
||||
C4153A8E1F8793DD001BA5EE /* small-logo.png */,
|
||||
5BAE202E208E1639006BF277 /* style.reference */,
|
||||
C410148D1F834D280022EE44 /* style.svg */,
|
||||
5BAE202D208E1638006BF277 /* textBasicTransform.reference */,
|
||||
5BAE2029208E1638006BF277 /* transform.reference */,
|
||||
C46E83541F94B20E00208037 /* transform.svg */,
|
||||
5BAE2026208E1637006BF277 /* triangle.reference */,
|
||||
57CAB12D1D7832E000FD8E47 /* triangle.svg */,
|
||||
5BAEA9CA206CEB7D0049AAAE /* viewBox.reference */,
|
||||
C43B06521F989D9300787A35 /* transform.reference */,
|
||||
C43B06541F98A53600787A35 /* group.reference */,
|
||||
C43B06561F98A7B700787A35 /* arcsgroup.reference */,
|
||||
C43B06581F98A84200787A35 /* style.reference */,
|
||||
C43B065A1F98A9E000787A35 /* clipManual.reference */,
|
||||
C43B065E1F98AAA500787A35 /* clip.reference */,
|
||||
C43B06601F98ACFC00787A35 /* textBasicTransform.reference */,
|
||||
5BAE2031208E163B006BF277 /* viewBox.reference */,
|
||||
5BAEA9C8206CEAA20049AAAE /* viewBox.svg */,
|
||||
);
|
||||
path = svg;
|
||||
sourceTree = "<group>";
|
||||
@ -803,6 +837,7 @@
|
||||
57E5E1451E3B393900D1CB28 /* svg */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5BAE201E208E1211006BF277 /* SVGCanvas.swift */,
|
||||
57E5E1461E3B393900D1CB28 /* SVGConstants.swift */,
|
||||
57E5E1471E3B393900D1CB28 /* SVGParser.swift */,
|
||||
57E5E1481E3B393900D1CB28 /* SVGParserError.swift */,
|
||||
@ -871,14 +906,27 @@
|
||||
A7E675541EC4211E00BD9ECB /* Bounds */,
|
||||
5713C4F11E5AD35900BBA4D9 /* Animation */,
|
||||
57CAB1241D7832E000FD8E47 /* svg */,
|
||||
5BAE205A208F2504006BF277 /* w3cSVGTests */,
|
||||
57CAB1221D782DFC00FD8E47 /* TestUtils.swift */,
|
||||
57FCD27B1D76EA4600CC0FB6 /* MacawTests.swift */,
|
||||
C4820B191F458D64008CE0FF /* MacawSVGTests.swift */,
|
||||
5BAE2057208F24DE006BF277 /* SceneSerialization.swift */,
|
||||
57FCD27D1D76EA4600CC0FB6 /* Info.plist */,
|
||||
);
|
||||
path = MacawTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5BAE205A208F2504006BF277 /* w3cSVGTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5BAE2060208F2504006BF277 /* color-prop-02-f-manual.reference */,
|
||||
5BAE205B208F2504006BF277 /* color-prop-02-f-manual.svg */,
|
||||
5BAE205D208F2504006BF277 /* shapes-circle-01-t-manual.reference */,
|
||||
5BAE205C208F2504006BF277 /* shapes-circle-01-t-manual.svg */,
|
||||
);
|
||||
path = w3cSVGTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A718CD2C1F45BC5300966E06 /* Platform */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1067,39 +1115,50 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5BAE203C208E163D006BF277 /* triangle.reference in Resources */,
|
||||
C4153A8F1F8793DE001BA5EE /* small-logo.png in Resources */,
|
||||
5BAE2061208F2504006BF277 /* color-prop-02-f-manual.svg in Resources */,
|
||||
5BAE2048208E163D006BF277 /* line.reference in Resources */,
|
||||
57CAB1361D7832E000FD8E47 /* triangle.svg in Resources */,
|
||||
C43B06691F99FC2300787A35 /* pathbounds4.svg in Resources */,
|
||||
C43B06631F99A33400787A35 /* pathbounds3.svg in Resources */,
|
||||
5BAEA9C9206CEAA20049AAAE /* viewBox.svg in Resources */,
|
||||
5BAE204B208E163D006BF277 /* clip.reference in Resources */,
|
||||
C43B064D1F9738EF00787A35 /* clip.svg in Resources */,
|
||||
5BAE2040208E163D006BF277 /* ellipse.reference in Resources */,
|
||||
57B7A4E11EE70DA5009D78D7 /* logo_base64.txt in Resources */,
|
||||
5BAE2047208E163D006BF277 /* viewBox.reference in Resources */,
|
||||
5BAE2042208E163D006BF277 /* group.reference in Resources */,
|
||||
C43B06671F99EE7300787A35 /* cubicRelative.svg in Resources */,
|
||||
C43B06571F98A7B700787A35 /* arcsgroup.reference in Resources */,
|
||||
C43B06531F989D9300787A35 /* transform.reference in Resources */,
|
||||
C43B06611F98ACFC00787A35 /* textBasicTransform.reference in Resources */,
|
||||
5BAE204A208E163D006BF277 /* roundRect.reference in Resources */,
|
||||
5BAE203E208E163D006BF277 /* circle.reference in Resources */,
|
||||
C43B064D1F9738EF00787A35 /* clip.svg in Resources */,
|
||||
57B7A4E11EE70DA5009D78D7 /* logo_base64.txt in Resources */,
|
||||
C43B06591F98A84200787A35 /* style.reference in Resources */,
|
||||
C43B065F1F98AAA500787A35 /* clip.reference in Resources */,
|
||||
C410148E1F834D290022EE44 /* style.svg in Resources */,
|
||||
5BAE2063208F2504006BF277 /* shapes-circle-01-t-manual.reference in Resources */,
|
||||
C4BD40BB1F8F58B0003034F0 /* pathbounds1.svg in Resources */,
|
||||
C43B065B1F98A9E000787A35 /* clipManual.reference in Resources */,
|
||||
C4BD40BC1F8F58B0003034F0 /* pathbounds2.svg in Resources */,
|
||||
5BAE2039208E163D006BF277 /* polygon.reference in Resources */,
|
||||
5BAE2043208E163D006BF277 /* textBasicTransform.reference in Resources */,
|
||||
57CAB1301D7832E000FD8E47 /* group.svg in Resources */,
|
||||
5BAE2045208E163D006BF277 /* arcsgroup.reference in Resources */,
|
||||
5BAE2062208F2504006BF277 /* shapes-circle-01-t-manual.svg in Resources */,
|
||||
5BAE203F208E163D006BF277 /* transform.reference in Resources */,
|
||||
5BAE2038208E163D006BF277 /* polyline.reference in Resources */,
|
||||
C43B06661F99EE7300787A35 /* cubicAbsolute.svg in Resources */,
|
||||
C46E83551F94B20E00208037 /* transform.svg in Resources */,
|
||||
57CAB1351D7832E000FD8E47 /* roundRect.svg in Resources */,
|
||||
5BAE203D208E163D006BF277 /* clipManual.reference in Resources */,
|
||||
57CAB12E1D7832E000FD8E47 /* circle.svg in Resources */,
|
||||
5BAE2066208F2504006BF277 /* color-prop-02-f-manual.reference in Resources */,
|
||||
57CAB1331D7832E000FD8E47 /* polyline.svg in Resources */,
|
||||
5BAEA9CB206CEB7D0049AAAE /* viewBox.reference in Resources */,
|
||||
57CAB1311D7832E000FD8E47 /* line.svg in Resources */,
|
||||
57B7A4DF1EE70D17009D78D7 /* logo.png in Resources */,
|
||||
602C561D2081C984003AD452 /* rounded.svg in Resources */,
|
||||
57CAB1321D7832E000FD8E47 /* polygon.svg in Resources */,
|
||||
5BAE203A208E163D006BF277 /* rect.reference in Resources */,
|
||||
5BAE2044208E163D006BF277 /* style.reference in Resources */,
|
||||
57CAB12F1D7832E000FD8E47 /* ellipse.svg in Resources */,
|
||||
57CAB1341D7832E000FD8E47 /* rect.svg in Resources */,
|
||||
C43B06551F98A53600787A35 /* group.reference in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -1177,6 +1236,7 @@
|
||||
57614B1E1F83D15600875933 /* AnimOperators.swift in Sources */,
|
||||
57614B1F1F83D15600875933 /* Circle.swift in Sources */,
|
||||
57614B201F83D15600875933 /* Color.swift in Sources */,
|
||||
5BAE204C208E1EF4006BF277 /* SVGCanvas.swift in Sources */,
|
||||
57614B211F83D15600875933 /* PathSegment.swift in Sources */,
|
||||
57614B221F83D15600875933 /* ImageRenderer.swift in Sources */,
|
||||
57614B231F83D15600875933 /* PathFunctions.swift in Sources */,
|
||||
@ -1303,6 +1363,7 @@
|
||||
57E5E18C1E3B393900D1CB28 /* Circle.swift in Sources */,
|
||||
57E5E17D1E3B393900D1CB28 /* Color.swift in Sources */,
|
||||
57E5E1951E3B393900D1CB28 /* PathSegment.swift in Sources */,
|
||||
5BAE201F208E1211006BF277 /* SVGCanvas.swift in Sources */,
|
||||
57E5E1A41E3B393900D1CB28 /* ImageRenderer.swift in Sources */,
|
||||
57E5E1621E3B393900D1CB28 /* PathFunctions.swift in Sources */,
|
||||
C4820B181F458D0E008CE0FF /* SVGSerializer.swift in Sources */,
|
||||
@ -1402,6 +1463,7 @@
|
||||
C4BD40B81F8F55AB003034F0 /* SVGBoundsTest.swift in Sources */,
|
||||
5713C4F51E5AE2C300BBA4D9 /* CombineAnimationTests.swift in Sources */,
|
||||
57CAB1231D782DFC00FD8E47 /* TestUtils.swift in Sources */,
|
||||
5BAE2058208F24DE006BF277 /* SceneSerialization.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="100" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<!-- correct bounds
|
||||
<rect x="33.66" y="9.5" width="16.84" height="41.0" stroke="red" stroke-width="1" fill="none"/>
|
||||
|
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 342 B |
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<!-- correct bounds
|
||||
<rect x="49.5" y="49.5" width="51.0" height="17.57" stroke="red" stroke-width="1" fill="none"/>
|
||||
|
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 342 B |
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="200" height="200">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<!-- correct bounds
|
||||
<rect x="101.4" y="36.7" width="7.6" height="35.0" fill="none" stroke="red" />
|
||||
|
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 390 B |
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0"
|
||||
width="200" height="200">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- correct bounds
|
||||
<rect x="36.7" y="101.4" width="35.1" height="7.6" fill="none" stroke="red" />
|
||||
-->
|
||||
|
Before Width: | Height: | Size: 425 B After Width: | Height: | Size: 386 B |
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="100" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<!-- correct bounds
|
||||
<rect x="0.0" y="0.0" width="50.0" height="50.0" stroke="red" stroke-width="1" fill="none"/>
|
||||
|
Before Width: | Height: | Size: 739 B After Width: | Height: | Size: 714 B |
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<!-- correct bounds
|
||||
<rect x="9.5" y="27.0" width="171.0" height="106.0" stroke="red" stroke-width="1" fill="none"/>
|
||||
|
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 360 B |
@ -19,7 +19,8 @@ class MacawSVGTests: XCTestCase {
|
||||
do {
|
||||
if let path = bundle.path(forResource: referenceFile, ofType: "reference") {
|
||||
let clipReferenceContent = try String.init(contentsOfFile: path).trimmingCharacters(in: .newlines)
|
||||
XCTAssertEqual(SVGSerializer.serialize(node: node), clipReferenceContent)
|
||||
let result = SVGSerializer.serialize(node: node)
|
||||
XCTAssertEqual(result, clipReferenceContent)
|
||||
}
|
||||
} catch {
|
||||
print(error)
|
||||
@ -27,22 +28,25 @@ class MacawSVGTests: XCTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
func validate(_ test: String, withReference: Bool = false) {
|
||||
func validate(_ test: String) {
|
||||
let bundle = Bundle(for: type(of: TestUtils()))
|
||||
var ext = "svg"
|
||||
if withReference {
|
||||
ext = "reference"
|
||||
}
|
||||
do {
|
||||
if let path = bundle.path(forResource: test, ofType: ext) {
|
||||
let referenceContent = try String.init(contentsOfFile: path).trimmingCharacters(in: .newlines)
|
||||
let node = try SVGParser.parse(bundle:bundle, path: test)
|
||||
let testContent = SVGSerializer.serialize(node: node)
|
||||
.replacingOccurrences(of: "version=\"1.1\" ><g>", with: "version=\"1.1\" >")
|
||||
.replacingOccurrences(of: "defs><g>", with: "defs>")
|
||||
.replacingOccurrences(of: "</g></svg>", with: "</svg>")
|
||||
XCTAssertEqual(testContent, referenceContent)
|
||||
}
|
||||
let node = try SVGParser.parse(bundle: bundle, path: test)
|
||||
validate(node: node, referenceFile: test)
|
||||
} catch {
|
||||
print(error)
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func create(_ test: String) {
|
||||
let bundle = Bundle(for: type(of: TestUtils()))
|
||||
do {
|
||||
let path = bundle.path(forResource: test, ofType: "svg")?.replacingOccurrences(of: ".svg", with: ".reference")
|
||||
let node = try SVGParser.parse(bundle: bundle, path: test)
|
||||
let result = SVGSerializer.serialize(node: node)
|
||||
try result.write(to: URL(fileURLWithPath: path!), atomically: true, encoding: String.Encoding.utf8)
|
||||
} catch {
|
||||
print(error)
|
||||
XCTFail()
|
||||
@ -99,19 +103,19 @@ class MacawSVGTests: XCTestCase {
|
||||
}
|
||||
|
||||
func testViewBox() {
|
||||
validate("viewBox", withReference: true)
|
||||
validate("viewBox")
|
||||
}
|
||||
|
||||
func testClipWithParser() {
|
||||
validate("clip", withReference: true)
|
||||
validate("clip")
|
||||
}
|
||||
|
||||
func testCSSStyleReference() {
|
||||
validate("style", withReference: true)
|
||||
validate("style")
|
||||
}
|
||||
|
||||
func testSVGTransformSkew() {
|
||||
validate("transform", withReference: true)
|
||||
validate("transform")
|
||||
}
|
||||
|
||||
func testSVGEllipse() {
|
||||
@ -123,7 +127,7 @@ class MacawSVGTests: XCTestCase {
|
||||
}
|
||||
|
||||
func testSVGGroup() {
|
||||
validate("group", withReference: true)
|
||||
validate("group")
|
||||
}
|
||||
|
||||
func testSVGLine() {
|
||||
@ -149,4 +153,55 @@ class MacawSVGTests: XCTestCase {
|
||||
func testSVGTriangle() {
|
||||
validate("triangle")
|
||||
}
|
||||
|
||||
func validateJSON(node: Node, referenceFile: String) {
|
||||
let bundle = Bundle(for: type(of: TestUtils()))
|
||||
|
||||
do {
|
||||
if let path = bundle.path(forResource: referenceFile, ofType: "reference"), let node = node as? Serializable {
|
||||
let referenceContent = try String(contentsOfFile: path)
|
||||
|
||||
let jsonData = try JSONSerialization.data(withJSONObject: node.toDictionary(), options: .prettyPrinted)
|
||||
let nodeContent = String(data: jsonData, encoding: String.Encoding.utf8)
|
||||
|
||||
XCTAssertEqual(nodeContent, referenceContent)
|
||||
}
|
||||
} catch {
|
||||
XCTFail(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
func validateJSON(_ test: String) {
|
||||
let bundle = Bundle(for: type(of: TestUtils()))
|
||||
do {
|
||||
let node = try SVGParser.parse(bundle: bundle, path: test)
|
||||
validateJSON(node: node, referenceFile: test)
|
||||
} catch {
|
||||
XCTFail(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
func createJSON(_ test: String) {
|
||||
let bundle = Bundle(for: type(of: TestUtils()))
|
||||
do {
|
||||
let path = bundle.path(forResource: test, ofType: "svg")?.replacingOccurrences(of: ".svg", with: ".reference")
|
||||
let node = try SVGParser.parse(bundle: bundle, path: test)
|
||||
guard let serializableNode = node as? Serializable else {
|
||||
XCTFail()
|
||||
return
|
||||
}
|
||||
let jsonData = try JSONSerialization.data(withJSONObject: serializableNode.toDictionary(), options: .prettyPrinted)
|
||||
try jsonData.write(to: URL(fileURLWithPath: path!))
|
||||
} catch {
|
||||
XCTFail(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
func testColorProp02() {
|
||||
validateJSON("color-prop-02-f-manual")
|
||||
}
|
||||
|
||||
func testShapesCircle01() {
|
||||
validateJSON("shapes-circle-01-t-manual")
|
||||
}
|
||||
}
|
||||
|
462
MacawTests/SceneSerialization.swift
Normal file
@ -0,0 +1,462 @@
|
||||
//
|
||||
// SceneSerialization.swift
|
||||
// MacawTests
|
||||
//
|
||||
// Created by Alisa Mylnikova on 23/04/2018.
|
||||
// Copyright © 2018 Exyte. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Macaw
|
||||
|
||||
protocol Initializable {
|
||||
init()
|
||||
}
|
||||
|
||||
extension Double : Initializable {}
|
||||
extension Bool : Initializable {}
|
||||
extension Int : Initializable {}
|
||||
|
||||
func parse<T: Initializable>(_ from: Any?) -> T {
|
||||
return from as? T ?? T()
|
||||
}
|
||||
|
||||
protocol Serializable {
|
||||
func toDictionary() -> [String:Any]
|
||||
}
|
||||
|
||||
class NodeSerializer {
|
||||
|
||||
var factories = [String:([String:Any]) -> Node]()
|
||||
|
||||
let locusSerializer = LocusSerializer()
|
||||
|
||||
init() {
|
||||
factories["Shape"] = { dictionary in
|
||||
let locusDict = dictionary["form"] as! [String:Any]
|
||||
let locus = self.locusSerializer.instance(dictionary: locusDict)
|
||||
|
||||
let shape = Shape(form: locus)
|
||||
|
||||
if let fillDict = dictionary["fill"] as? [String:Any], let fillType = fillDict["type"] as? String, fillType == "Color" {
|
||||
shape.fill = Color(dictionary: fillDict)
|
||||
}
|
||||
if let strokeDict = dictionary["stroke"] as? [String:Any] {
|
||||
shape.stroke = Stroke(dictionary: strokeDict)
|
||||
}
|
||||
|
||||
return shape
|
||||
}
|
||||
factories["Text"] = { dictionary in
|
||||
let textString = dictionary["text"] as! String
|
||||
let text = Text(text: textString)
|
||||
|
||||
if let fontDict = dictionary["font"] as? [String:Any] {
|
||||
text.font = Font(dictionary: fontDict)
|
||||
}
|
||||
if let fillDict = dictionary["fill"] as? [String:Any],
|
||||
let fillType = fillDict["type"] as? String,
|
||||
fillType == "Color",
|
||||
let color = Color(dictionary: fillDict) {
|
||||
text.fill = color
|
||||
}
|
||||
if let strokeDict = dictionary["stroke"] as? [String:Any] {
|
||||
text.stroke = Stroke(dictionary: strokeDict)
|
||||
}
|
||||
if let alignString = dictionary["align"] as? String {
|
||||
text.align = Align.instantiate(string: alignString)
|
||||
}
|
||||
if let baselineString = dictionary["baseline"] as? String {
|
||||
text.baseline = baselineForString(baselineString)
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
factories["Group"] = { dictionary in
|
||||
let contents = dictionary["contents"] as! [[String:Any]]
|
||||
var nodes = [Node]()
|
||||
for dict in contents {
|
||||
nodes.append(self.instance(dictionary: dict))
|
||||
}
|
||||
return Group(contents: nodes)
|
||||
}
|
||||
}
|
||||
|
||||
func instance(dictionary: [String:Any]) -> Node {
|
||||
let type = dictionary["node"] as! String
|
||||
let node = factories[type]!(dictionary)
|
||||
node.place = Transform(string: dictionary["place"] as? String)
|
||||
node.opaque = Bool(dictionary["opaque"] as? String ?? "") ?? true
|
||||
node.opacity = Double(dictionary["opacity"] as? String ?? "") ?? 0
|
||||
if let locusDict = dictionary["clip"] as? [String:Any] {
|
||||
node.clip = locusSerializer.instance(dictionary: locusDict)
|
||||
}
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
||||
extension Node {
|
||||
|
||||
func baseToDictionary() -> [String:Any] {
|
||||
var result = ["place": place.toString(), "opaque": String(describing: opaque), "opacity": String(describing: opacity)] as [String : Any]
|
||||
if let clip = clip as? Serializable {
|
||||
result["clip"] = clip.toDictionary()
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
extension Shape: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
var result = super.baseToDictionary()
|
||||
result["node"] = "Shape"
|
||||
if let form = form as? Serializable {
|
||||
result["form"] = form.toDictionary()
|
||||
}
|
||||
if let fillColor = fill as? Color {
|
||||
result["fill"] = fillColor.toDictionary()
|
||||
}
|
||||
if let stroke = stroke {
|
||||
result["stroke"] = stroke.toDictionary()
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
extension Text: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
var result = super.baseToDictionary()
|
||||
result["node"] = "Text"
|
||||
result["text"] = text
|
||||
if let font = font {
|
||||
result["font"] = font.toDictionary()
|
||||
}
|
||||
if let fillColor = fill as? Color {
|
||||
result["fill"] = fillColor.toDictionary()
|
||||
}
|
||||
if let stroke = stroke {
|
||||
result["stroke"] = stroke.toDictionary()
|
||||
}
|
||||
result["align"] = align.toString()
|
||||
result["baseline"] = "\(baseline)"
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
extension Group: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
var nodes = [[String:Any]]()
|
||||
for node in contents {
|
||||
if let node = node as? Serializable {
|
||||
nodes.append(node.toDictionary())
|
||||
}
|
||||
}
|
||||
var result = super.baseToDictionary()
|
||||
result["node"] = "Group"
|
||||
result["contents"] = nodes
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class LocusSerializer {
|
||||
|
||||
var factories = [String:([String:Any]) -> Locus]()
|
||||
|
||||
init() {
|
||||
factories["Arc"] = { dictionary in
|
||||
Arc(ellipse: self.instance(dictionary: dictionary["Ellipse"] as! [String:Any]) as! Ellipse,
|
||||
shift: parse(dictionary["shift"]),
|
||||
extent: parse(dictionary["extent"]))
|
||||
}
|
||||
factories["Circle"] = { dictionary in
|
||||
Circle(cx: parse(dictionary["cx"]),
|
||||
cy: parse(dictionary["cy"]),
|
||||
r: parse(dictionary["r"]))
|
||||
}
|
||||
factories["Ellipse"] = { dictionary in
|
||||
Ellipse(cx: parse(dictionary["cx"]),
|
||||
cy: parse(dictionary["cy"]),
|
||||
rx: parse(dictionary["rx"]),
|
||||
ry: parse(dictionary["rx"]))
|
||||
}
|
||||
factories["Line"] = { dictionary in
|
||||
Line(x1: parse(dictionary["x1"]),
|
||||
y1: parse(dictionary["y1"]),
|
||||
x2: parse(dictionary["x2"]),
|
||||
y2: parse(dictionary["y2"]))
|
||||
}
|
||||
factories["Path"] = { dictionary in
|
||||
let array = dictionary["segments"] as! [[String:Any]]
|
||||
var pathSegments = [PathSegment]()
|
||||
for dict in array {
|
||||
pathSegments.append(PathSegment(
|
||||
type: typeForString(dict["type"] as! String),
|
||||
data: dict["data"] as! [Double]))
|
||||
}
|
||||
return Path(segments: pathSegments)
|
||||
}
|
||||
factories["Polygon"] = { dictionary in
|
||||
Polygon.init(points: dictionary["points"] as! [Double])
|
||||
}
|
||||
factories["Polyline"] = { dictionary in
|
||||
Polyline.init(points: dictionary["points"] as! [Double])
|
||||
}
|
||||
factories["Rect"] = { dictionary in
|
||||
Rect(x: parse(dictionary["x"]),
|
||||
y: parse(dictionary["y"]),
|
||||
w: parse(dictionary["w"]),
|
||||
h: parse(dictionary["h"]))
|
||||
}
|
||||
factories["RoundRect"] = { dictionary in
|
||||
RoundRect(rect: self.instance(dictionary: dictionary["Rect"] as! [String:Any]) as! Rect,
|
||||
rx: parse(dictionary["rx"]),
|
||||
ry: parse(dictionary["ry"]))
|
||||
}
|
||||
}
|
||||
|
||||
func instance(dictionary: [String:Any]) -> Locus {
|
||||
let type = dictionary["type"] as! String
|
||||
return factories[type]!(dictionary)
|
||||
}
|
||||
}
|
||||
|
||||
extension Arc: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
return ["type": "Arc", "ellipse": ellipse.toDictionary(), "shift": shift, "extent": extent]
|
||||
}
|
||||
}
|
||||
|
||||
extension Circle: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
return ["type": "Circle", "cx": cx, "cy": cy, "r": r]
|
||||
}
|
||||
}
|
||||
|
||||
extension Ellipse: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
return ["type": "Ellipse", "cx": cx, "cy": cy, "rx": rx, "ry": ry]
|
||||
}
|
||||
}
|
||||
|
||||
extension Line: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
return ["type": "Line", "x1": x1, "y1": y1, "x2": x2, "y2": y2]
|
||||
}
|
||||
}
|
||||
|
||||
extension Path: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
var pathSegments = [[String:Any]]()
|
||||
for segment in segments {
|
||||
pathSegments.append(segment.toDictionary())
|
||||
}
|
||||
return ["type": "Path", "segments": pathSegments]
|
||||
}
|
||||
}
|
||||
|
||||
extension Polygon: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
return ["type": "Polygon", "points": points]
|
||||
}
|
||||
}
|
||||
|
||||
extension Polyline: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
return ["type": "Polyline", "points": points]
|
||||
}
|
||||
}
|
||||
|
||||
extension Rect: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
return ["type": "Rect", "x": x, "y": y, "w": w, "h": h]
|
||||
}
|
||||
}
|
||||
|
||||
extension RoundRect: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
return ["type": "RoundRect", "rect": rect.toDictionary(), "rx": rx, "ry": ry]
|
||||
}
|
||||
}
|
||||
|
||||
extension PathSegment: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
return ["type": "\(type)", "data": data]
|
||||
}
|
||||
}
|
||||
|
||||
extension Color: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
return ["type": "Color", "val": val]
|
||||
}
|
||||
|
||||
convenience init?(dictionary: [String:Any]) {
|
||||
self.init(val: dictionary["val"] as! Int)
|
||||
}
|
||||
}
|
||||
|
||||
extension Stroke: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
var result = ["width": width, "cap": "\(cap)", "join": "\(join)", "dashes": dashes] as [String : Any]
|
||||
if let fillColor = fill as? Color {
|
||||
result["fill"] = fillColor.toDictionary()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
convenience init?(dictionary: [String:Any]) {
|
||||
|
||||
guard let fillDict = dictionary["fill"] as? [String:Any], let fillType = fillDict["type"] as? String, fillType == "Color", let fill = Color(dictionary: fillDict) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
var cap = LineCap.butt
|
||||
if let lineCapString = dictionary["cap"] as? String {
|
||||
cap = lineCapForString(lineCapString)
|
||||
}
|
||||
|
||||
var join = LineJoin.miter
|
||||
if let lineJoinString = dictionary["join"] as? String {
|
||||
join = lineJoinForString(lineJoinString)
|
||||
}
|
||||
|
||||
let dashes = dictionary["dashes"] as? [Double] ?? []
|
||||
|
||||
self.init(fill: fill, width: parse(dictionary["width"]), cap: cap, join: join, dashes: dashes)
|
||||
}
|
||||
}
|
||||
|
||||
extension Font: Serializable {
|
||||
|
||||
func toDictionary() -> [String:Any] {
|
||||
return ["name": name, "size": size, "weight": weight]
|
||||
}
|
||||
|
||||
convenience init(dictionary: [String:Any]) {
|
||||
self.init(name: dictionary["name"] as? String ?? "Serif",
|
||||
size: parse(dictionary["size"]),
|
||||
weight: dictionary["weight"] as? String ?? "normal")
|
||||
}
|
||||
}
|
||||
|
||||
extension Transform {
|
||||
|
||||
func toString() -> String {
|
||||
let formatter = NumberFormatter()
|
||||
formatter.minimumFractionDigits = 0
|
||||
formatter.maximumFractionDigits = 6
|
||||
|
||||
let nums = [m11, m12, m21, m22, dx, dy]
|
||||
|
||||
var result = ""
|
||||
for num in nums {
|
||||
result += formatter.string(from: num as NSNumber) ?? "n/a"
|
||||
result += ", "
|
||||
}
|
||||
return result.dropLast(2) + ""
|
||||
}
|
||||
|
||||
convenience init(string: String?) {
|
||||
guard let string = string else {
|
||||
self.init()
|
||||
return
|
||||
}
|
||||
let vals = string.components(separatedBy: ", ").map{ Double($0) ?? 0 }
|
||||
if vals.count == 6 {
|
||||
self.init(m11: vals[0], m12: vals[1], m21: vals[2], m22: vals[3], dx: vals[4], dy: vals[5])
|
||||
} else {
|
||||
self.init()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Align {
|
||||
|
||||
func toString() -> String {
|
||||
if self === Align.mid {
|
||||
return "mid"
|
||||
}
|
||||
if self === Align.max {
|
||||
return "max"
|
||||
}
|
||||
return "min"
|
||||
}
|
||||
|
||||
static func instantiate(string: String) -> Align {
|
||||
switch string {
|
||||
case "mid":
|
||||
return .mid
|
||||
case "max":
|
||||
return .max
|
||||
default:
|
||||
return .min
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func typeForString(_ string: String) -> PathSegmentType {
|
||||
switch(string) {
|
||||
case "M": return .M
|
||||
case "m": return .m
|
||||
case "L": return .L
|
||||
case "l": return .l
|
||||
case "C": return .C
|
||||
case "c": return .c
|
||||
case "Q": return .Q
|
||||
case "q": return .q
|
||||
case "A": return .A
|
||||
case "a": return .a
|
||||
case "z", "Z": return .z
|
||||
case "H": return .H
|
||||
case "h": return .h
|
||||
case "V": return .V
|
||||
case "v": return .v
|
||||
case "S": return .S
|
||||
case "s": return .s
|
||||
case "T": return .T
|
||||
case "t": return .t
|
||||
default: return .M
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func lineCapForString(_ string: String) -> LineCap {
|
||||
switch(string) {
|
||||
case "butt": return .butt
|
||||
case "round": return .round
|
||||
case "square": return .square
|
||||
default: return .butt
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func lineJoinForString(_ string: String) -> LineJoin {
|
||||
switch(string) {
|
||||
case "miter": return .miter
|
||||
case "round": return .round
|
||||
case "bevel": return .bevel
|
||||
default: return .miter
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func baselineForString(_ string: String) -> Baseline {
|
||||
switch(string) {
|
||||
case "top": return .top
|
||||
case "alphabetic": return .alphabetic
|
||||
case "bottom": return .bottom
|
||||
case "mid": return .mid
|
||||
default: return .top
|
||||
}
|
||||
}
|
1
MacawTests/svg/circle.reference
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g><circle r="40" cy="50" cx="50" fill="red" stroke="black" stroke-width="3.0"/><circle r="40" cy="50" cx="140" fill="#F0F0AA" stroke="black" stroke-width="3.0"/></g></g></svg>
|
After Width: | Height: | Size: 282 B |
@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><defs><clipPath id="clipPath1"><path d="M 20 0m -20 0a 20 20 0 1 0 40 0a 20 20 0 1 0 -40 0M 0 10L 0 45L 100 45L 100 10z M 0 55L 0 90L 100 90L 100 55z " /></clipPath></defs><circle r="50" cy="50" cx="50" clip-path="url(#clipPath1)" fill="black"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><defs><clipPath id="clipPath1"><path d="M 20 0m -20 0a 20 20 0 1 0 40 0a 20 20 0 1 0 -40 0M 0 10L 0 45L 100 45L 100 10z M 0 55L 0 90L 100 90L 100 55z " /></clipPath></defs><g><circle r="50" cy="50" cx="50" clip-path="url(#clipPath1)" fill="black"/></g></svg>
|
Before Width: | Height: | Size: 355 B After Width: | Height: | Size: 361 B |
1
MacawTests/svg/ellipse.reference
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g><g><ellipse cy="80" ry="50" rx="100" cx="200" fill="yellow" stroke="purple" stroke-width="2.0"/></g></g></g></svg>
|
After Width: | Height: | Size: 221 B |
@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><path d="M 150 0L 75 200L 225 200z " fill="black" stroke="black" stroke-width="2.0"/><line y1="0" x2="200" x1="0" y2="200" fill="black" stroke="white" stroke-width="2.0"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g><path d="M 150 0L 75 200L 225 200z " fill="black" stroke="black" stroke-width="2.0"/><line y1="0" x2="200" x1="0" y2="200" fill="black" stroke="white" stroke-width="2.0"/></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 288 B After Width: | Height: | Size: 295 B |
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<svg version="1.1" id="group" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="210" width="400">
|
||||
<svg version="1.1" id="group" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g style="stroke:#000000;stroke-width:2">
|
||||
<path d="M 150 0 L 75 200 L 225 200 Z" />
|
||||
<line x1="0" y1="0" x2="200" y2="200" stroke="#ffffff"/>
|
||||
|
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 307 B |
1
MacawTests/svg/line.reference
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g><line y1="0" x2="200" x1="0" y2="200" fill="black" stroke="red" stroke-width="2.0"/></g></g></svg>
|
After Width: | Height: | Size: 205 B |
1
MacawTests/svg/polygon.reference
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g><polygon points="200.0,10.0,250.0,190.0,160.0,210.0" fill="black"/></g></g></svg>
|
After Width: | Height: | Size: 188 B |
1
MacawTests/svg/polyline.reference
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g><polyline points="0.0,40.0,40.0,40.0,40.0,80.0,80.0,80.0,80.0,120.0,120.0,120.0,120.0,160.0" fill="white" stroke="red" stroke-width="4.0"/></g></g></svg>
|
After Width: | Height: | Size: 260 B |
1
MacawTests/svg/rect.reference
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g><rect height="150" x="50" y="0" width="150" fill="black"/></g></g></svg>
|
After Width: | Height: | Size: 179 B |
1
MacawTests/svg/roundRect.reference
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g><rect height="150" ry="20" rx="20" width="150" fill="black"/></g></g></svg>
|
After Width: | Height: | Size: 182 B |
@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><circle r="10" cy="50" cx="50" fill="white" stroke="#231F20" stroke-width="1.5"/><circle r="10" cy="50" cx="80" fill="black"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g><circle r="10" cy="50" cx="50" fill="white" stroke="#231F20" stroke-width="1.5"/><circle r="10" cy="50" cx="80" fill="black"/></g></g></svg>
|
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 249 B |
@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g transform="matrix(2.0,1.0,1.0,1.0,0.0,0.0)" ><rect height="5" x="0" y="0" width="150" fill="blue"/><rect height="50" x="0" y="0" width="5" fill="red"/><rect height="50" x="150" y="0" width="5" fill="black"/><rect height="5" x="0" y="50" width="150" fill="black"/><ellipse cy="25" ry="15" rx="40" cx="75" fill="purple"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g transform="matrix(2.0,1.0,1.0,1.0,0.0,0.0)" ><rect height="5" x="0" y="0" width="150" fill="blue"/><rect height="50" x="0" y="0" width="5" fill="red"/><rect height="50" x="150" y="0" width="5" fill="black"/><rect height="5" x="0" y="50" width="150" fill="black"/><ellipse cy="25" ry="15" rx="40" cx="75" fill="purple"/></g></g></svg>
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 448 B |
1
MacawTests/svg/triangle.reference
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g><path d="M 150 0L 75 200L 225 200z " fill="black" stroke="black" stroke-width="2.0"/></g></g></svg>
|
After Width: | Height: | Size: 206 B |
@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><defs><clipPath id="clipPath1"><rect height="400" x="100" y="50" width="400" /></clipPath></defs><g clip-path="url(#clipPath1)" transform="matrix(0.444444444444444,0.0,0.0,0.444444444444444,-5.55555555555554,-22.2222222222222)" ><g><g><ellipse cy="80" ry="50" rx="100" cx="200" fill="yellow" stroke="purple" stroke-width="2.0"/></g></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><defs><clipPath id="clipPath1"><rect height="400" x="100" y="50" width="400" /></clipPath></defs><g clip-path="url(#clipPath1)" transform="matrix(0.444444444444444,0.0,0.0,0.444444444444444,-5.55555555555554,-22.2222222222222)" ><g><g><ellipse cy="80" ry="50" rx="100" cx="200" fill="yellow" stroke="purple" stroke-width="2.0"/></g></g></g></svg>
|
Before Width: | Height: | Size: 446 B After Width: | Height: | Size: 449 B |
14
MacawTests/w3c-test-suite.md
Normal file
@ -0,0 +1,14 @@
|
||||
## W3C SVG Test Suite Coverage
|
||||
|
||||
Total: 6
|
||||
|
||||
Passed: 33%
|
||||
|
||||
|Name |Status |
|
||||
|------|-------|
|
||||
|[color-prop-01-b-manual](w3cSVGTests/color-prop-01-b-manual.svg) | ❌ |
|
||||
|[color-prop-02-f-manual](w3cSVGTests/color-prop-02-f-manual.svg) | ✅ |
|
||||
|[color-prop-03-t-manual](w3cSVGTests/color-prop-03-t-manual.svg) | [#123](https://github.com/exyte/Macaw/issues/123) |
|
||||
|[color-prop-04-t-manual](w3cSVGTests/color-prop-04-t-manual.svg) | [#42](https://github.com/exyte/Macaw/issues/42) |
|
||||
|[color-prop-05-t-manual](w3cSVGTests/color-prop-05-t-manual.svg) | ❌ |
|
||||
|[shapes-circle-01-t-manual](w3cSVGTests/shapes-circle-01-t-manual.svg) | ✅ |
|
722
MacawTests/w3cSVGTests/color-prop-02-f-manual.reference
Normal file
@ -0,0 +1,722 @@
|
||||
{
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 40,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 75
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 14423100
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 40,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 115
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 14423100
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 80,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 75
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 14423100
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 80,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 115
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 14423100
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 40,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 200
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 10025880
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 40,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 240
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 10025880
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 80,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 200
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 10025880
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 80,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 240
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 10025880
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 40,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 325
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 4286945
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 40,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 365
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 4286945
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 80,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 325
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 4286945
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 80,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 365
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 4286945
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 135,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 75
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 11674146
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 135,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 115
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 11674146
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 175,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 75
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 11674146
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 175,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 115
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 11674146
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 135,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 200
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 3050327
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 135,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 240
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 3050327
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 175,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 200
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 3050327
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 175,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 240
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 3050327
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 135,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 325
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 205
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 135,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 365
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 205
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 175,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 325
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 205
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 175,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 365
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 205
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 230,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 75
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 13458524
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 230,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 115
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 13458524
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 270,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 75
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 13458524
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 270,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 115
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 13458524
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 230,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 200
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 8190976
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 230,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 240
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 8190976
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 270,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 200
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 8190976
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 270,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 240
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 8190976
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 230,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 325
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 4772300
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 230,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 365
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 4772300
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 270,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 325
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 4772300
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 270,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 365
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 4772300
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"baseline" : "bottom",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 0
|
||||
},
|
||||
"node" : "Text",
|
||||
"align" : "min",
|
||||
"text" : "$Revision: 1.9 $",
|
||||
"opacity" : "1.0",
|
||||
"place" : "1, 0, 0, 1, 10, 340",
|
||||
"opaque" : "true",
|
||||
"font" : {
|
||||
"name" : "SVGFreeSansASCII,sans-serif",
|
||||
"size" : 32,
|
||||
"weight" : "normal"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"x" : 1,
|
||||
"w" : 478,
|
||||
"type" : "Rect",
|
||||
"y" : 1,
|
||||
"h" : 358
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"stroke" : {
|
||||
"join" : "miter",
|
||||
"cap" : "butt",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 0
|
||||
},
|
||||
"dashes" : [
|
||||
|
||||
],
|
||||
"width" : 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"clip" : {
|
||||
"x" : 0,
|
||||
"w" : 480,
|
||||
"type" : "Rect",
|
||||
"y" : 0,
|
||||
"h" : 360
|
||||
}
|
||||
}
|
113
MacawTests/w3cSVGTests/color-prop-02-f-manual.svg
Executable file
@ -0,0 +1,113 @@
|
||||
<svg version="1.1" baseProfile="full" id="svg-root"
|
||||
width="100%" height="100%" viewBox="0 0 480 360"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!--======================================================================-->
|
||||
<!--= SVG 1.1 2nd Edition Test Case =-->
|
||||
<!--======================================================================-->
|
||||
<!--= Copyright 2009 World Wide Web Consortium, (Massachusetts =-->
|
||||
<!--= Institute of Technology, European Research Consortium for =-->
|
||||
<!--= Informatics and Mathematics (ERCIM), Keio University). =-->
|
||||
<!--= All Rights Reserved. =-->
|
||||
<!--= See http://www.w3.org/Consortium/Legal/. =-->
|
||||
<!--======================================================================-->
|
||||
<d:SVGTestCase xmlns:d="http://www.w3.org/2000/02/svg/testsuite/description/"
|
||||
template-version="1.4" reviewer="SVGWG" author="Chris Lilley" status="accepted"
|
||||
version="$Revision: 1.9 $" testname="$RCSfile: color-prop-02-f.svg,v $">
|
||||
<d:testDescription xmlns="http://www.w3.org/1999/xhtml" href="http://www.w3.org/TR/SVG11/color.html#ColorProperty">
|
||||
<p>
|
||||
Tests if the color datatype is supported. There are multiple syntaxes for
|
||||
specifying the same color, such as #37F and #3377FF. This test is focussed on the
|
||||
X11 color names, which are not part of the tiny profile.
|
||||
Each group of circles uses four forms - 6-digit hex, rbg() integer form, rgb() percentage form,
|
||||
and named ('X11') colors. It does not use 3-digit hex, because the colors used in this test
|
||||
cannot be represented in three digit form.
|
||||
</p>
|
||||
</d:testDescription>
|
||||
<d:operatorScript xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p>
|
||||
Run the test. No interaction required.
|
||||
</p>
|
||||
</d:operatorScript>
|
||||
<d:passCriteria xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p>
|
||||
For each of the nine groups of circles shown here, all circles must
|
||||
be identical in color, and the same color as in the reference image.
|
||||
</p>
|
||||
</d:passCriteria>
|
||||
</d:SVGTestCase>
|
||||
<title id="test-title">$RCSfile: color-prop-02-f.svg,v $</title>
|
||||
<defs>
|
||||
<font-face font-family="SVGFreeSansASCII" unicode-range="U+0-7F">
|
||||
<font-face-src>
|
||||
<font-face-uri xlink:href="../resources/SVGFreeSans.svg#ascii"/>
|
||||
</font-face-src>
|
||||
</font-face>
|
||||
</defs>
|
||||
<g id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
|
||||
<!-- groups of five colors -->
|
||||
<g>
|
||||
<circle cx="75" cy="40" r="20" fill="crimson"/>
|
||||
<circle cx="115" cy="40" r="20" fill="#DC143C"/>
|
||||
<circle cx="75" cy="80" r="20" fill="rgb(220,20,60)"/>
|
||||
<circle cx="115" cy="80" r="20" fill="rgb(86.274509803921568627450980392157%,7.8431372549019607843137254901961%,23.529411764705882352941176470588%)"/>
|
||||
</g>
|
||||
<g>
|
||||
<circle cx="200" cy="40" r="20" fill="palegreen"/>
|
||||
<circle cx="240" cy="40" r="20" fill="#98FB98"/>
|
||||
<circle cx="200" cy="80" r="20" fill="rgb(152, 251, 152)"/>
|
||||
<circle cx="240" cy="80" r="20" fill="rgb(59.60784313725490196078431372549%,98.431372549019607843137254901961%,59.60784313725490196078431372549%)"/>
|
||||
</g>
|
||||
<g>
|
||||
<circle cx="325" cy="40" r="20" fill="royalblue"/>
|
||||
<circle cx="365" cy="40" r="20" fill="#4169E1"/>
|
||||
<circle cx="325" cy="80" r="20" fill="rgb(65, 105, 225)"/>
|
||||
<circle cx="365" cy="80" r="20" fill="rgb(25.490196078431372549019607843137%,41.176470588235294117647058823529%,88.235294117647058823529411764706%)"/>
|
||||
</g>
|
||||
<g>
|
||||
<circle cx="75" cy="135" r="20" fill="firebrick"/>
|
||||
<circle cx="115" cy="135" r="20" fill="#B22222"/>
|
||||
<circle cx="75" cy="175" r="20" fill="rgb(178,34,34)"/>
|
||||
<circle cx="115" cy="175" r="20" fill="rgb(69.803921568627450980392156862745%,13.333333333333333333333333333333%,13.333333333333333333333333333333%)"/>
|
||||
</g>
|
||||
<g>
|
||||
<circle cx="200" cy="135" r="20" fill="seagreen"/>
|
||||
<circle cx="240" cy="135" r="20" fill="#2E8B57"/>
|
||||
<circle cx="200" cy="175" r="20" fill="rgb(46, 139, 87)"/>
|
||||
<circle cx="240" cy="175" r="20" fill="rgb(18.039215686274509803921568627451%,54.509803921568627450980392156863%,34.117647058823529411764705882353%)"/>
|
||||
</g>
|
||||
<g>
|
||||
<circle cx="325" cy="135" r="20" fill="mediumblue"/>
|
||||
<circle cx="365" cy="135" r="20" fill="#0000CD"/>
|
||||
<circle cx="325" cy="175" r="20" fill="rgb(0, 0, 205)"/>
|
||||
<circle cx="365" cy="175" r="20" fill="rgb(0%,0%,80.39215686274509803921568627451%)"/>
|
||||
</g>
|
||||
<g>
|
||||
<circle cx="75" cy="230" r="20" fill="indianred"/>
|
||||
<circle cx="115" cy="230" r="20" fill="#CD5C5C"/>
|
||||
<circle cx="75" cy="270" r="20" fill="rgb(205, 92, 92)"/>
|
||||
<circle cx="115" cy="270" r="20" fill="rgb(80.39215686274509803921568627451%,36.078431372549019607843137254902%,36.078431372549019607843137254902%)"/>
|
||||
</g>
|
||||
<g>
|
||||
<circle cx="200" cy="230" r="20" fill="lawngreen"/>
|
||||
<circle cx="240" cy="230" r="20" fill="#7CFC00"/>
|
||||
<circle cx="200" cy="270" r="20" fill="rgb(124, 252, 0)"/>
|
||||
<circle cx="240" cy="270" r="20" fill="rgb(48.627450980392156862745098039216%,98.823529411764705882352941176471%,0%)"/>
|
||||
</g>
|
||||
<g>
|
||||
<circle cx="325" cy="230" r="20" fill="mediumturquoise"/>
|
||||
<circle cx="365" cy="230" r="20" fill="#48D1CC"/>
|
||||
<circle cx="325" cy="270" r="20" fill="rgb(72, 209, 204)"/>
|
||||
<circle cx="365" cy="270" r="20" fill="rgb(28.235294117647058823529411764706%,81.960784313725490196078431372549%,80%)"/>
|
||||
</g>
|
||||
</g>
|
||||
<g font-family="SVGFreeSansASCII,sans-serif" font-size="32">
|
||||
<text id="revision" x="10" y="340" stroke="none" fill="black">$Revision: 1.9 $</text>
|
||||
</g>
|
||||
<rect id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000000"/>
|
||||
<!-- comment out this watermark once the test is approved -->
|
||||
<!--<g id="draft-watermark">
|
||||
<rect x="1" y="1" width="478" height="20" fill="red" stroke="black" stroke-width="1"/>
|
||||
<text font-family="SVGFreeSansASCII,sans-serif" font-weight="bold" font-size="20" x="240"
|
||||
text-anchor="middle" y="18" stroke-width="0.5" stroke="black" fill="white">DRAFT</text>
|
||||
</g>-->
|
||||
</svg>
|
After Width: | Height: | Size: 6.2 KiB |
222
MacawTests/w3cSVGTests/shapes-circle-01-t-manual.reference
Normal file
@ -0,0 +1,222 @@
|
||||
{
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 100,
|
||||
"type" : "Circle",
|
||||
"r" : 50,
|
||||
"cx" : 100
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"stroke" : {
|
||||
"join" : "miter",
|
||||
"cap" : "butt",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 0
|
||||
},
|
||||
"dashes" : [
|
||||
|
||||
],
|
||||
"width" : 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"form" : {
|
||||
"cy" : 100,
|
||||
"type" : "Circle",
|
||||
"r" : 35,
|
||||
"cx" : 220
|
||||
},
|
||||
"node" : "Shape",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 32768
|
||||
},
|
||||
"opacity" : "1.0",
|
||||
"stroke" : {
|
||||
"join" : "miter",
|
||||
"cap" : "butt",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 0
|
||||
},
|
||||
"dashes" : [
|
||||
|
||||
],
|
||||
"width" : 1
|
||||
},
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"opaque" : "true"
|
||||
},
|
||||
{
|
||||
"form" : {
|
||||
"cy" : 100,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 340
|
||||
},
|
||||
"node" : "Shape",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 0
|
||||
},
|
||||
"opacity" : "1.0",
|
||||
"stroke" : {
|
||||
"join" : "miter",
|
||||
"cap" : "butt",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 65280
|
||||
},
|
||||
"dashes" : [
|
||||
|
||||
],
|
||||
"width" : 4
|
||||
},
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"opaque" : "true"
|
||||
},
|
||||
{
|
||||
"form" : {
|
||||
"cy" : 260,
|
||||
"type" : "Circle",
|
||||
"r" : 20,
|
||||
"cx" : 100
|
||||
},
|
||||
"node" : "Shape",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 16776960
|
||||
},
|
||||
"opacity" : "1.0",
|
||||
"stroke" : {
|
||||
"join" : "miter",
|
||||
"cap" : "butt",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 65280
|
||||
},
|
||||
"dashes" : [
|
||||
|
||||
],
|
||||
"width" : 4
|
||||
},
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"opaque" : "true"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 260,
|
||||
"type" : "Circle",
|
||||
"r" : 35,
|
||||
"cx" : 220
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 255
|
||||
},
|
||||
"opacity" : "1.0"
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"cy" : 260,
|
||||
"type" : "Circle",
|
||||
"r" : 50,
|
||||
"cx" : 340
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"stroke" : {
|
||||
"join" : "miter",
|
||||
"cap" : "butt",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 32768
|
||||
},
|
||||
"dashes" : [
|
||||
|
||||
],
|
||||
"width" : 10
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"contents" : [
|
||||
{
|
||||
"baseline" : "bottom",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 0
|
||||
},
|
||||
"node" : "Text",
|
||||
"align" : "min",
|
||||
"text" : "$Revision: 1.7 $",
|
||||
"opacity" : "1.0",
|
||||
"place" : "1, 0, 0, 1, 10, 340",
|
||||
"opaque" : "true",
|
||||
"font" : {
|
||||
"name" : "SVGFreeSansASCII,sans-serif",
|
||||
"size" : 32,
|
||||
"weight" : "normal"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"form" : {
|
||||
"x" : 1,
|
||||
"w" : 478,
|
||||
"type" : "Rect",
|
||||
"y" : 1,
|
||||
"h" : 358
|
||||
},
|
||||
"node" : "Shape",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"stroke" : {
|
||||
"join" : "miter",
|
||||
"cap" : "butt",
|
||||
"fill" : {
|
||||
"type" : "Color",
|
||||
"val" : 0
|
||||
},
|
||||
"dashes" : [
|
||||
|
||||
],
|
||||
"width" : 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"place" : "1, 0, 0, 1, 0, 0",
|
||||
"node" : "Group",
|
||||
"opaque" : "true",
|
||||
"opacity" : "1.0",
|
||||
"clip" : {
|
||||
"x" : 0,
|
||||
"w" : 480,
|
||||
"type" : "Rect",
|
||||
"y" : 0,
|
||||
"h" : 360
|
||||
}
|
||||
}
|
58
MacawTests/w3cSVGTests/shapes-circle-01-t-manual.svg
Executable file
@ -0,0 +1,58 @@
|
||||
<svg version="1.1" baseProfile="tiny" id="svg-root"
|
||||
width="100%" height="100%" viewBox="0 0 480 360"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!--======================================================================-->
|
||||
<!--= SVG 1.1 2nd Edition Test Case =-->
|
||||
<!--======================================================================-->
|
||||
<!--= Copyright 2009 World Wide Web Consortium, (Massachusetts =-->
|
||||
<!--= Institute of Technology, European Research Consortium for =-->
|
||||
<!--= Informatics and Mathematics (ERCIM), Keio University). =-->
|
||||
<!--= All Rights Reserved. =-->
|
||||
<!--= See http://www.w3.org/Consortium/Legal/. =-->
|
||||
<!--======================================================================-->
|
||||
<d:SVGTestCase xmlns:d="http://www.w3.org/2000/02/svg/testsuite/description/"
|
||||
template-version="1.4" reviewer="SVGWG" author="Lofton Henderson" status="accepted"
|
||||
version="$Revision: 1.7 $" testname="$RCSfile: shapes-circle-01-t.svg,v $">
|
||||
<d:testDescription xmlns="http://www.w3.org/1999/xhtml" href="http://www.w3.org/TR/SVG11/shapes.html#CircleElement">
|
||||
<p>
|
||||
Tests the circle element
|
||||
</p>
|
||||
</d:testDescription>
|
||||
<d:operatorScript xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p>
|
||||
Run the test. No interaction required.
|
||||
</p>
|
||||
</d:operatorScript>
|
||||
<d:passCriteria xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p>
|
||||
Six circles are displayed, with position, size, fill and stroke matching the reference image
|
||||
</p>
|
||||
</d:passCriteria>
|
||||
</d:SVGTestCase>
|
||||
<title id="test-title">$RCSfile: shapes-circle-01-t.svg,v $</title>
|
||||
<defs>
|
||||
<font-face font-family="SVGFreeSansASCII" unicode-range="U+0-7F">
|
||||
<font-face-src>
|
||||
<font-face-uri xlink:href="../resources/SVGFreeSans.svg#ascii"/>
|
||||
</font-face-src>
|
||||
</font-face>
|
||||
</defs>
|
||||
<g id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
|
||||
<circle cx="100" cy="100" r="50" fill="none" stroke="black"/>
|
||||
<circle cx="220" cy="100" r="35" fill="green" stroke="black"/>
|
||||
<circle cx="340" cy="100" r="20" fill="black" stroke="lime" stroke-width="4"/>
|
||||
<circle cx="100" cy="260" r="20" stroke="lime" fill="yellow" stroke-width="4"/>
|
||||
<circle cx="220" cy="260" r="35" stroke="none" fill="blue"/>
|
||||
<circle cx="340" cy="260" r="50" stroke="green" fill="none" stroke-width="10"/>
|
||||
</g>
|
||||
<g font-family="SVGFreeSansASCII,sans-serif" font-size="32">
|
||||
<text id="revision" x="10" y="340" stroke="none" fill="black">$Revision: 1.7 $</text>
|
||||
</g>
|
||||
<rect id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000000"/>
|
||||
<!-- comment out this watermark once the test is approved -->
|
||||
<!--<g id="draft-watermark">
|
||||
<rect x="1" y="1" width="478" height="20" fill="red" stroke="black" stroke-width="1"/>
|
||||
<text font-family="SVGFreeSansASCII,sans-serif" font-weight="bold" font-size="20" x="240"
|
||||
text-anchor="middle" y="18" stroke-width="0.5" stroke="black" fill="white">DRAFT</text>
|
||||
</g>-->
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
@ -9,21 +9,18 @@
|
||||
class ShapeAnimation: AnimationImpl<Shape> {
|
||||
convenience init(animatedNode: Shape, finalValue: Shape, animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
||||
|
||||
let nodeId = animatedNode.id
|
||||
let interpolationFunc = { (t: Double) -> Shape in
|
||||
if t == 0 {
|
||||
let initialNode = Node.nodeBy(id: nodeId) as! Shape
|
||||
|
||||
return Shape(form: initialNode.form,
|
||||
fill: initialNode.fill,
|
||||
stroke: initialNode.stroke,
|
||||
place: initialNode.place,
|
||||
opaque: initialNode.opaque,
|
||||
opacity: initialNode.opacity,
|
||||
clip: initialNode.clip,
|
||||
effect: initialNode.effect,
|
||||
visible: initialNode.visible,
|
||||
tag: initialNode.tag)
|
||||
return Shape(form: animatedNode.form,
|
||||
fill: animatedNode.fill,
|
||||
stroke: animatedNode.stroke,
|
||||
place: animatedNode.place,
|
||||
opaque: animatedNode.opaque,
|
||||
opacity: animatedNode.opacity,
|
||||
clip: animatedNode.clip,
|
||||
effect: animatedNode.effect,
|
||||
visible: animatedNode.visible,
|
||||
tag: animatedNode.tag)
|
||||
}
|
||||
|
||||
return finalValue
|
||||
@ -56,6 +53,25 @@ class ShapeAnimation: AnimationImpl<Shape> {
|
||||
override public func pause() {
|
||||
stop()
|
||||
}
|
||||
|
||||
open override func reverse() -> Animation {
|
||||
let factory = { () -> (Double) -> Shape in
|
||||
let original = self.timeFactory()
|
||||
return { (t: Double) -> Shape in
|
||||
return original(1.0 - t)
|
||||
}
|
||||
}
|
||||
|
||||
let node = Node.nodeBy(id: nodeId!)
|
||||
let reversedAnimation = ShapeAnimation(animatedNode: node as! Shape,
|
||||
factory: factory,
|
||||
animationDuration: duration,
|
||||
fps: logicalFps)
|
||||
reversedAnimation.progress = progress
|
||||
reversedAnimation.completion = completion
|
||||
|
||||
return reversedAnimation
|
||||
}
|
||||
}
|
||||
|
||||
public extension AnimatableVariable {
|
||||
|
@ -1,11 +1,17 @@
|
||||
import Foundation
|
||||
|
||||
public enum FillRule {
|
||||
case nonzero, evenodd
|
||||
}
|
||||
|
||||
open class Path: Locus {
|
||||
|
||||
open let segments: [PathSegment]
|
||||
open let fillRule: FillRule
|
||||
|
||||
public init(segments: [PathSegment] = []) {
|
||||
public init(segments: [PathSegment] = [], fillRule: FillRule = .nonzero) {
|
||||
self.segments = segments
|
||||
self.fillRule = fillRule
|
||||
}
|
||||
|
||||
override open func bounds() -> Rect {
|
||||
|
@ -77,6 +77,10 @@ extension MFont {
|
||||
class var mSystemFontSize: CGFloat {
|
||||
return UIFont.systemFontSize
|
||||
}
|
||||
|
||||
class var mFamilyNames: [String] {
|
||||
return UIFont.familyNames
|
||||
}
|
||||
}
|
||||
|
||||
extension UIScreen {
|
||||
|
@ -92,6 +92,10 @@ extension NSFont {
|
||||
class var mSystemFontSize: CGFloat {
|
||||
return NSFont.systemFontSize
|
||||
}
|
||||
|
||||
class var mFamilyNames: [String] {
|
||||
return NSFontManager.shared.availableFontFamilies
|
||||
}
|
||||
}
|
||||
|
||||
extension NSScreen {
|
||||
|
@ -90,26 +90,28 @@ class RenderUtils {
|
||||
fatalError("Unsupported node: \(node)")
|
||||
}
|
||||
|
||||
static let availableFonts = MFont.mFamilyNames.map{ $0.lowercased() }
|
||||
|
||||
class func loadFont(name: String, size: Int) -> MFont? {
|
||||
let separationSet = CharacterSet(charactersIn: ",")
|
||||
let names = name.components(separatedBy: separationSet)
|
||||
var customFont: MFont? = .none
|
||||
names.forEach { fontName in
|
||||
if customFont != .none {
|
||||
return
|
||||
|
||||
let fontPriorities = name.split(separator: ",").map{ String($0).trimmingCharacters(in: CharacterSet(charactersIn: " '")).lowercased() }
|
||||
for font in fontPriorities {
|
||||
if availableFonts.contains(font) {
|
||||
return MFont(name: font, size: CGFloat(size))
|
||||
}
|
||||
|
||||
if fontName.first == " " {
|
||||
let index = fontName.index(fontName.startIndex, offsetBy: 1)
|
||||
let fixedName = String(fontName.suffix(from: index))
|
||||
customFont = MFont(name: fixedName, size: CGFloat(size))
|
||||
return
|
||||
|
||||
if font == "serif" {
|
||||
return MFont(name: "Georgia", size: CGFloat(size))
|
||||
}
|
||||
if font == "sans-serif" {
|
||||
return MFont(name: "Arial", size: CGFloat(size))
|
||||
}
|
||||
if font == "monospace" {
|
||||
return MFont(name: "Courier", size: CGFloat(size))
|
||||
}
|
||||
|
||||
customFont = MFont(name: fontName, size: CGFloat(size))
|
||||
}
|
||||
|
||||
return customFont
|
||||
return .none
|
||||
}
|
||||
|
||||
class func applyOpacity(_ color: Color, opacity: Double) -> Color {
|
||||
|
@ -38,7 +38,12 @@ class ShapeRenderer: NodeRenderer {
|
||||
|
||||
if shape.fill != nil || shape.stroke != nil {
|
||||
setGeometry(shape.form, ctx: ctx.cgContext!)
|
||||
drawPath(shape.fill, stroke: shape.stroke, ctx: ctx.cgContext!, opacity: opacity)
|
||||
|
||||
var fillRule = FillRule.nonzero
|
||||
if let path = shape.form as? Path {
|
||||
fillRule = path.fillRule
|
||||
}
|
||||
drawPath(shape.fill, stroke: shape.stroke, ctx: ctx.cgContext!, opacity: opacity, fillRule: fillRule)
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,7 +107,7 @@ class ShapeRenderer: NodeRenderer {
|
||||
return CGRect(x: CGFloat(rect.x), y: CGFloat(rect.y), width: CGFloat(rect.w), height: CGFloat(rect.h))
|
||||
}
|
||||
|
||||
fileprivate func drawPath(_ fill: Fill?, stroke: Stroke?, ctx: CGContext?, opacity: Double) {
|
||||
fileprivate func drawPath(_ fill: Fill?, stroke: Stroke?, ctx: CGContext?, opacity: Double, fillRule: FillRule) {
|
||||
var shouldStrokePath = false
|
||||
if fill is Gradient || stroke?.fill is Gradient {
|
||||
shouldStrokePath = true
|
||||
@ -112,15 +117,15 @@ class ShapeRenderer: NodeRenderer {
|
||||
let path = ctx!.path
|
||||
setFill(fill, ctx: ctx, opacity: opacity)
|
||||
if stroke.fill is Gradient && !(fill is Gradient) {
|
||||
ctx!.drawPath(using: .fill)
|
||||
ctx!.drawPath(using: fillRule == .nonzero ? .fill : .eoFill)
|
||||
}
|
||||
drawWithStroke(stroke, ctx: ctx, opacity: opacity, shouldStrokePath: shouldStrokePath, path: path, mode: .fillStroke)
|
||||
drawWithStroke(stroke, ctx: ctx, opacity: opacity, shouldStrokePath: shouldStrokePath, path: path, mode: fillRule == .nonzero ? .fillStroke : .eoFillStroke)
|
||||
return
|
||||
}
|
||||
|
||||
if let fill = fill {
|
||||
setFill(fill, ctx: ctx, opacity: opacity)
|
||||
ctx!.drawPath(using: .fill)
|
||||
ctx!.drawPath(using: fillRule == .nonzero ? .fill : .eoFill)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -79,18 +79,18 @@ class TextRenderer: NodeRenderer {
|
||||
guard let text = text else {
|
||||
return MFont.systemFont(ofSize: 18.0)
|
||||
}
|
||||
|
||||
if let textFont = text.font {
|
||||
if let customFont = RenderUtils.loadFont(name: textFont.name, size: textFont.size) {
|
||||
return customFont
|
||||
} else {
|
||||
if let weight = getWeight(textFont.weight) {
|
||||
return MFont.systemFont(ofSize: CGFloat(textFont.size), weight: weight)
|
||||
}
|
||||
return MFont.systemFont(ofSize: CGFloat(textFont.size))
|
||||
}
|
||||
guard let textFont = text.font else {
|
||||
return MFont.systemFont(ofSize: MFont.mSystemFontSize)
|
||||
}
|
||||
|
||||
if let customFont = RenderUtils.loadFont(name: textFont.name, size: textFont.size) {
|
||||
return customFont
|
||||
} else {
|
||||
if let weight = getWeight(textFont.weight) {
|
||||
return MFont.systemFont(ofSize: CGFloat(textFont.size), weight: weight)
|
||||
}
|
||||
return MFont.systemFont(ofSize: CGFloat(textFont.size))
|
||||
}
|
||||
return MFont.systemFont(ofSize: MFont.mSystemFontSize)
|
||||
}
|
||||
|
||||
fileprivate func getWeight(_ weight: String) -> MFont.Weight? {
|
||||
|
@ -42,10 +42,10 @@ open class SVGParser {
|
||||
}
|
||||
|
||||
let availableStyleAttributes = ["stroke", "stroke-width", "stroke-opacity", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
|
||||
"fill", "text-anchor", "clip-path", "fill-opacity",
|
||||
"fill", "fill-rule", "text-anchor", "clip-path", "fill-opacity",
|
||||
"stop-color", "stop-opacity",
|
||||
"font-family", "font-size",
|
||||
"font-weight", "opacity", "color"]
|
||||
"font-weight", "opacity", "color", "visibility"]
|
||||
|
||||
fileprivate let xmlString: String
|
||||
fileprivate let initialPosition: Transform
|
||||
@ -88,12 +88,15 @@ open class SVGParser {
|
||||
}
|
||||
}
|
||||
parseSvg(parsedXml.children)
|
||||
|
||||
let group = Group(contents: self.nodes, place: initialPosition)
|
||||
|
||||
if let viewBoxParams = viewBoxParams {
|
||||
let group = viewBoxParams.svgSize != nil ?
|
||||
SVGCanvas(bounds: Rect(x: 0, y: 0, w: viewBoxParams.svgSize!.w, h: viewBoxParams.svgSize!.h), contents: nodes) :
|
||||
Group(contents: nodes)
|
||||
addViewBoxClip(toNode: group, viewBoxParams: viewBoxParams)
|
||||
return group
|
||||
}
|
||||
return group
|
||||
return Group(contents: nodes)
|
||||
}
|
||||
|
||||
fileprivate func prepareSvg(_ children: [XMLIndexer]) {
|
||||
@ -262,11 +265,18 @@ open class SVGParser {
|
||||
if styleAttributes["display"] == "none" {
|
||||
return .none
|
||||
}
|
||||
if styleAttributes["visibility"] == "hidden" {
|
||||
return .none
|
||||
}
|
||||
|
||||
|
||||
let position = getPosition(element)
|
||||
switch element.name {
|
||||
case "path":
|
||||
if let path = parsePath(node) {
|
||||
if var path = parsePath(node) {
|
||||
if let rule = getFillRule(styleAttributes) {
|
||||
path = Path(segments: path.segments, fillRule: rule)
|
||||
}
|
||||
return Shape(form: path, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes), tag: getTag(element))
|
||||
}
|
||||
case "line":
|
||||
@ -629,13 +639,8 @@ open class SVGParser {
|
||||
}
|
||||
|
||||
fileprivate func getStrokeWidth(_ styleParts: [String: String]) -> Double {
|
||||
if let strokeWidth = styleParts["stroke-width"] {
|
||||
let characterSet = NSCharacterSet.decimalDigits.union(NSCharacterSet.punctuationCharacters).inverted
|
||||
let digitsArray = strokeWidth.components(separatedBy: characterSet)
|
||||
let digits = digitsArray.joined()
|
||||
if let value = Double(digits) {
|
||||
return value
|
||||
}
|
||||
if let strokeWidth = styleParts["stroke-width"], let value = doubleFromString(strokeWidth) {
|
||||
return value
|
||||
}
|
||||
return 1
|
||||
}
|
||||
@ -836,7 +841,7 @@ open class SVGParser {
|
||||
if let anchor = textAnchor {
|
||||
if anchor == "middle" {
|
||||
return .mid
|
||||
} else if anchor == "right" {
|
||||
} else if anchor == "end" {
|
||||
return .max
|
||||
}
|
||||
}
|
||||
@ -1261,17 +1266,14 @@ open class SVGParser {
|
||||
}
|
||||
|
||||
fileprivate func getFontName(_ attributes: [String: String]) -> String? {
|
||||
return attributes["font-family"]
|
||||
return attributes["font-family"]?.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
}
|
||||
|
||||
fileprivate func getFontSize(_ attributes: [String: String]) -> Int? {
|
||||
guard let fontSize = attributes["font-size"] else {
|
||||
guard let fontSize = attributes["font-size"], let size = doubleFromString(fontSize) else {
|
||||
return .none
|
||||
}
|
||||
if let size = Double(fontSize) {
|
||||
return (Int(round(size)))
|
||||
}
|
||||
return .none
|
||||
return Int(round(size))
|
||||
}
|
||||
|
||||
fileprivate func getFontStyle(_ attributes: [String: String], style: String) -> Bool? {
|
||||
@ -1331,6 +1333,20 @@ open class SVGParser {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fileprivate func getFillRule(_ attributes: [String: String]) -> FillRule? {
|
||||
if let rule = attributes["fill-rule"] {
|
||||
switch rule {
|
||||
case "nonzero":
|
||||
return .nonzero
|
||||
case "evenodd":
|
||||
return .evenodd
|
||||
default:
|
||||
return .none
|
||||
}
|
||||
}
|
||||
return .none
|
||||
}
|
||||
|
||||
fileprivate func copyNode(_ referenceNode: Node) -> Node? {
|
||||
let pos = referenceNode.place
|
||||
|