Skip to content

Commit 32c858d

Browse files
committed
Make SVGPath functions public
1 parent 1890370 commit 32c858d

File tree

3 files changed

+61
-28
lines changed

3 files changed

+61
-28
lines changed

ShapeScript.xcodeproj/project.pbxproj

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
011E57B529F57BC600CA0778 /* WhatsNew.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 011E57B429F57BBC00CA0778 /* WhatsNew.rtf */; };
1818
01326AFF215D617500BB8CB1 /* Scene+SceneKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01326AFE215D617500BB8CB1 /* Scene+SceneKit.swift */; };
1919
013312D321C9BBCC00626F1B /* EvaluationContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 013312D221C9BBCC00626F1B /* EvaluationContext.swift */; };
20+
013888CC2B7A990800EDABE9 /* Euclid+SVGPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 013888CB2B7A990800EDABE9 /* Euclid+SVGPath.swift */; };
2021
013A0FC1290905C40015FD28 /* ShapeScript.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 01BFB39621425C8500E47A7C /* ShapeScript.framework */; platformFilters = (ios, tvos, xros, ); };
2122
013A0FC2290905C40015FD28 /* Euclid.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 016FAC2321C149C300AF60DC /* Euclid.framework */; platformFilters = (ios, tvos, xros, ); };
2223
013A0FC3290905C40015FD28 /* LRUCache.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 01FDE3C026BD736700A46F66 /* LRUCache.framework */; platformFilters = (ios, tvos, xros, ); };
@@ -31,6 +32,7 @@
3132
01460C3321D63F3300BFC4FF /* Euclid.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 016FAC2321C149C300AF60DC /* Euclid.framework */; };
3233
01460C3921D63FA200BFC4FF /* Euclid.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 016FAC2321C149C300AF60DC /* Euclid.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
3334
01460C3B21D6406500BFC4FF /* ShapeScript.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 01BFB39621425C8500E47A7C /* ShapeScript.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
35+
0146C7012B828ACD00FC9D81 /* SVGPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0146C7002B828ACD00FC9D81 /* SVGPathTests.swift */; };
3436
014F85D9215B890100461FB7 /* Interpreter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014F85D8215B890100461FB7 /* Interpreter.swift */; };
3537
014F85DB215BE1A900461FB7 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014F85DA215BE1A900461FB7 /* Parser.swift */; };
3638
0152E5DA214500C50082A5A3 /* ShapeScript.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 01BFB39621425C8500E47A7C /* ShapeScript.framework */; };
@@ -118,7 +120,6 @@
118120
01E3AA0526CB8E8200E0B287 /* Value+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01E3AA0426CB8E8200E0B287 /* Value+Logging.swift */; };
119121
01E3AA0A26CB920000E0B287 /* LoggingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01E3AA0926CB920000E0B287 /* LoggingTests.swift */; };
120122
01E5A4F328EE3DFC00EE7CD9 /* Examples in Resources */ = {isa = PBXBuildFile; fileRef = 01BD943521936514005FFAEC /* Examples */; };
121-
01F01A4D2804CC5300FA1EBB /* SVGPath+Path.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F01A4C2804CC5300FA1EBB /* SVGPath+Path.swift */; };
122123
01F1A6182806BD1A00A1621B /* StandardLibraryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F1A6172806BD1A00A1621B /* StandardLibraryTests.swift */; };
123124
01F1A703280AD2BA00A1621B /* StringMatchingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F1A702280AD2BA00A1621B /* StringMatchingTests.swift */; };
124125
01F1A7A5280F724600A1621B /* Material+Brightness.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F1A7A1280F724600A1621B /* Material+Brightness.swift */; };
@@ -342,8 +343,10 @@
342343
011E57B429F57BBC00CA0778 /* WhatsNew.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = WhatsNew.rtf; sourceTree = "<group>"; };
343344
01326AFE215D617500BB8CB1 /* Scene+SceneKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Scene+SceneKit.swift"; sourceTree = "<group>"; };
344345
013312D221C9BBCC00626F1B /* EvaluationContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EvaluationContext.swift; sourceTree = "<group>"; };
346+
013888CB2B7A990800EDABE9 /* Euclid+SVGPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Euclid+SVGPath.swift"; sourceTree = "<group>"; };
345347
013DB0BD21C8731C00DFB0D2 /* StandardLibrary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardLibrary.swift; sourceTree = "<group>"; };
346348
013FBF692834D7EF00EAF795 /* Types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = "<group>"; };
349+
0146C7002B828ACD00FC9D81 /* SVGPathTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SVGPathTests.swift; sourceTree = "<group>"; };
347350
014F85D8215B890100461FB7 /* Interpreter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Interpreter.swift; sourceTree = "<group>"; };
348351
014F85DA215BE1A900461FB7 /* Parser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; };
349352
0152E5C5214500990082A5A3 /* ShapeScript Viewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ShapeScript Viewer.app"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -424,7 +427,6 @@
424427
01DE96762A085DC40080DB79 /* CLI+Export.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CLI+Export.swift"; sourceTree = "<group>"; };
425428
01E3AA0426CB8E8200E0B287 /* Value+Logging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Value+Logging.swift"; sourceTree = "<group>"; };
426429
01E3AA0926CB920000E0B287 /* LoggingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingTests.swift; sourceTree = "<group>"; };
427-
01F01A4C2804CC5300FA1EBB /* SVGPath+Path.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SVGPath+Path.swift"; sourceTree = "<group>"; };
428430
01F1A6172806BD1A00A1621B /* StandardLibraryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardLibraryTests.swift; sourceTree = "<group>"; };
429431
01F1A702280AD2BA00A1621B /* StringMatchingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringMatchingTests.swift; sourceTree = "<group>"; };
430432
01F1A7A1280F724600A1621B /* Material+Brightness.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Material+Brightness.swift"; sourceTree = "<group>"; };
@@ -656,7 +658,7 @@
656658
01CF787126EA36AD0097907A /* String+Ordinals.swift */,
657659
01C8AAB226F0B28A0055F522 /* String+Matching.swift */,
658660
0104EB7D271F66A000B60058 /* Euclid+Extensions.swift */,
659-
01F01A4C2804CC5300FA1EBB /* SVGPath+Path.swift */,
661+
013888CB2B7A990800EDABE9 /* Euclid+SVGPath.swift */,
660662
0118098228F216D200E0C8D8 /* Value+JSON.swift */,
661663
01E3AA0426CB8E8200E0B287 /* Value+Logging.swift */,
662664
01BFB39A21425C8500E47A7C /* Info.plist */,
@@ -680,6 +682,7 @@
680682
017F72FD28270F290023231C /* PlatformTests.swift */,
681683
01111309269A0AD600BE9490 /* MetadataTests.swift */,
682684
0107A0562A7326D800AD33A1 /* RegressionTests.swift */,
685+
0146C7002B828ACD00FC9D81 /* SVGPathTests.swift */,
683686
01C6F9BF284A6E52000B57B1 /* TestDelegate.swift */,
684687
01BFB3A621425C8500E47A7C /* Info.plist */,
685688
);
@@ -1124,6 +1127,7 @@
11241127
buildActionMask = 2147483647;
11251128
files = (
11261129
01994BF82B3EB7EE004DE69C /* EvaluationDelegate.swift in Sources */,
1130+
013888CC2B7A990800EDABE9 /* Euclid+SVGPath.swift in Sources */,
11271131
01CF787226EA36AD0097907A /* String+Ordinals.swift in Sources */,
11281132
014F85D9215B890100461FB7 /* Interpreter.swift in Sources */,
11291133
01E3AA0526CB8E8200E0B287 /* Value+Logging.swift in Sources */,
@@ -1137,7 +1141,6 @@
11371141
014F85DB215BE1A900461FB7 /* Parser.swift in Sources */,
11381142
01F1A9B7281F41DE00A1621B /* Symbols.swift in Sources */,
11391143
01326AFF215D617500BB8CB1 /* Scene+SceneKit.swift in Sources */,
1140-
01F01A4D2804CC5300FA1EBB /* SVGPath+Path.swift in Sources */,
11411144
01DE96712A082A6A0080DB79 /* ProgramError.swift in Sources */,
11421145
0118098328F216D200E0C8D8 /* Value+JSON.swift in Sources */,
11431146
01977FCB215D0BD400D65D5E /* Scene.swift in Sources */,
@@ -1163,6 +1166,7 @@
11631166
01A9CA4028BB483500440FDA /* GeometryTests.swift in Sources */,
11641167
01A6FE832AEF5D2A006AE113 /* MemberTests.swift in Sources */,
11651168
0111130A269A0AD600BE9490 /* MetadataTests.swift in Sources */,
1169+
0146C7012B828ACD00FC9D81 /* SVGPathTests.swift in Sources */,
11661170
01C6F9C0284A6E52000B57B1 /* TestDelegate.swift in Sources */,
11671171
01F1A703280AD2BA00A1621B /* StringMatchingTests.swift in Sources */,
11681172
01E3AA0A26CB920000E0B287 /* LoggingTests.swift in Sources */,
Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// SVGPath+Path.swift
2+
// Euclid+SVGPath.swift
33
// ShapeScript Lib
44
//
55
// Created by Nick Lockwood on 11/04/2022.
@@ -12,28 +12,45 @@ import Euclid
1212
import SVGPath
1313
#endif
1414

15-
extension Vector {
16-
init(_ svgPoint: SVGPoint) {
17-
self.init(svgPoint.x, svgPoint.y)
15+
public extension SVGPoint {
16+
/// Creates an `SVGPoint` from a Euclid `Vector`.
17+
/// - Parameter point: A Euclid vector.
18+
init(_ point: Vector) {
19+
self.init(x: point.x, y: point.y)
1820
}
1921
}
2022

21-
extension SVGPoint {
22-
init(_ point: Vector) {
23-
self.init(x: point.x, y: point.y)
23+
public extension SVGPath {
24+
/// Creates an`SVGPath` from a Euclid `Path`.
25+
/// - Parameter path: The `Path` to convert.
26+
init(_ path: Path) {
27+
self.init(commands: path.subpaths.flatMap { path -> [SVGCommand] in
28+
guard let start = path.points.first?.position else { return [] }
29+
var commands: [SVGCommand] = [.moveTo(SVGPoint(start))]
30+
for point in path.points.dropFirst() {
31+
commands.append(.lineTo(.init(point.position)))
32+
}
33+
commands.append(.end)
34+
return commands
35+
})
2436
}
2537
}
2638

27-
extension Path {
28-
/// Creates a path from an SVGPath
29-
init(_ svgPath: SVGPath, detail: Int = 4, color: Color? = nil) {
30-
self.init(subpaths: svgPath.paths(detail: detail, color: color))
39+
public extension Vector {
40+
/// Creates a `Vector` from an `SVGPoint`.
41+
/// - Parameter svgPoint: An SVG point.
42+
init(_ svgPoint: SVGPoint) {
43+
self.init(svgPoint.x, svgPoint.y)
3144
}
3245
}
3346

34-
extension SVGPath {
35-
/// Creates an array of paths from an SVGPath
36-
func paths(detail: Int = 4, color: Color? = nil) -> [Path] {
47+
public extension Path {
48+
/// Creates a `Path` from an `SVGPath`.
49+
/// - Parameters:
50+
/// - svgPath: The `SVGPath` to convert.
51+
/// - detail: The detail level to apply when converting curves to line segments.
52+
/// - color: An optional `Color` to apply to the path.
53+
init(_ svgPath: SVGPath, detail: Int = 4, color: Color? = nil) {
3754
var paths = [Path]()
3855
var points = [PathPoint]()
3956
var startingPoint = Vector.zero
@@ -166,27 +183,21 @@ extension SVGPath {
166183
}
167184
lastCommand = command
168185
}
169-
commands.forEach(addCommand)
186+
svgPath.commands.forEach(addCommand)
170187
endPath()
171-
return paths
188+
self.init(subpaths: paths)
172189
}
173190
}
174191

175-
private func quadraticBezier(
176-
_ p0: Double, _ p1: Double,
177-
_ p2: Double, _ t: Double
178-
) -> Double {
192+
private func quadraticBezier(_ p0: Double, _ p1: Double, _ p2: Double, _ t: Double) -> Double {
179193
let oneMinusT = 1 - t
180194
let c0 = oneMinusT * oneMinusT * p0
181195
let c1 = 2 * oneMinusT * t * p1
182196
let c2 = t * t * p2
183197
return c0 + c1 + c2
184198
}
185199

186-
private func cubicBezier(
187-
_ p0: Double, _ p1: Double,
188-
_ p2: Double, _ p3: Double, _ t: Double
189-
) -> Double {
200+
private func cubicBezier(_ p0: Double, _ p1: Double, _ p2: Double, _ p3: Double, _ t: Double) -> Double {
190201
let oneMinusT = 1 - t
191202
let oneMinusTSquared = oneMinusT * oneMinusT
192203
let c0 = oneMinusTSquared * oneMinusT * p0
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// SVGPathTests.swift
3+
// ShapeScriptTests
4+
//
5+
// Created by Nick Lockwood on 18/02/2024.
6+
// Copyright © 2024 Nick Lockwood. All rights reserved.
7+
//
8+
9+
import Euclid
10+
import ShapeScript
11+
import SVGPath
12+
import XCTest
13+
14+
class SVGPathTests: XCTestCase {
15+
func testNoCrashWithEmptyPath() {
16+
XCTAssertEqual(SVGPath(Path.empty), SVGPath(commands: []))
17+
}
18+
}

0 commit comments

Comments
 (0)