Skip to content

Commit 8092372

Browse files
committed
Add explicit font value type
1 parent aed5bb7 commit 8092372

7 files changed

Lines changed: 71 additions & 13 deletions

File tree

ShapeScript/Members.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ extension ValueType {
124124
"words": .list(.string),
125125
"characters": .list(.string),
126126
"linespacing": .optional(.number),
127-
"font": .optional(.string),
127+
"font": .optional(.font),
128+
"name": .string,
128129
]
129130
}
130131

@@ -201,6 +202,8 @@ extension Value {
201202
members += color.members
202203
}
203204
return members
205+
case .font:
206+
return ["name"]
204207
case .text:
205208
return ["string", "font", "color", "linespacing"]
206209
case let .object(values):
@@ -438,12 +441,19 @@ extension Value {
438441
default:
439442
return nil
440443
}
444+
case let .font(font):
445+
switch name {
446+
case "name":
447+
return .string(font)
448+
default:
449+
return nil
450+
}
441451
case let .text(text):
442452
switch name {
443453
case "string":
444454
return .string(text.string)
445455
case "font":
446-
return text.font.map { .string($0) } ?? .void
456+
return text.font.map { .font($0) } ?? .void
447457
case "color":
448458
return text.color.map { .color($0) } ?? .void
449459
case "linespacing":
@@ -470,7 +480,7 @@ extension Value {
470480
guard let values = range.stride.map(Array.init) else { fallthrough }
471481
return -values.endIndex ..< values.endIndex
472482
case .boolean, .texture, .number, .radians, .halfturns, .material, .rotation,
473-
.string, .text, .path, .mesh, .polygon, .point, .bounds, .object:
483+
.string, .font, .text, .path, .mesh, .polygon, .point, .bounds, .object:
474484
return 0 ..< 0
475485
}
476486
}
@@ -501,7 +511,7 @@ extension Value {
501511
let index = index < 0 ? values.count + index : index
502512
return values.indices.contains(index) ? .number(values[index]) : nil
503513
case .boolean, .texture, .number, .radians, .halfturns, .material, .rotation,
504-
.string, .text, .path, .mesh, .polygon, .point, .bounds, .object:
514+
.string, .font, .text, .path, .mesh, .polygon, .point, .bounds, .object:
505515
return nil
506516
}
507517
}
@@ -515,7 +525,7 @@ private extension [Value] {
515525
return values.flattened
516526
case .color, .texture, .material, .boolean, .number,
517527
.radians, .halfturns, .vector, .size, .rotation,
518-
.string, .text, .path, .mesh, .polygon, .point,
528+
.string, .font, .text, .path, .mesh, .polygon, .point,
519529
.range, .bounds, .object:
520530
return [$0]
521531
}

ShapeScript/StandardLibrary.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ extension Symbols {
602602
"font": .property(.font, { parameter, context in
603603
context.font = parameter.stringValue
604604
}, { context in
605-
.string(context.font)
605+
.font(context.font)
606606
}),
607607
]
608608

ShapeScript/Types.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ extension Value {
342342
case .size: return .size
343343
case .rotation: return .rotation
344344
case .string: return .string
345+
case .font: return .font
345346
case .text: return .text
346347
case .path: return .path
347348
case .mesh: return .mesh
@@ -451,7 +452,7 @@ extension Value {
451452
case (.string, .color):
452453
// TODO: support named colors
453454
return Color(hexString: stringValue).map { .color($0) }
454-
case (.boolean, .string), (.number, .string), (.texture(.file), .string):
455+
case (.boolean, .string), (.number, .string), (.font, .string), (.texture(.file), .string):
455456
return .string(stringValue)
456457
case let (.tuple(values), .string):
457458
let stringifyable = values.allSatisfy { $0.isConvertible(to: .string) }

ShapeScript/Value+Logging.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ extension RangeValue: Loggable {
385385
}
386386

387387
extension Value: Loggable {
388-
public var loggableValue: Loggable {
388+
private var loggableValue: Loggable {
389389
// Note: this switch is technically not needed, but serves to
390390
// ensure logging conformance is not forgotten for new types
391391
switch self {
@@ -400,6 +400,7 @@ extension Value: Loggable {
400400
case let .size(size): return size
401401
case let .rotation(rotation): return rotation
402402
case let .string(string): return string
403+
case let .font(font): return font
403404
case let .text(text): return text
404405
case let .path(path): return path
405406
case let .mesh(mesh): return mesh

ShapeScript/Values.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ enum Value: Hashable {
2121
case size(Vector)
2222
case rotation(Rotation)
2323
case string(String)
24+
case font(String)
2425
case text(TextValue)
2526
case path(Path)
2627
case mesh(Geometry)
@@ -182,6 +183,7 @@ extension Value {
182183
case let .size(size): return size
183184
case let .rotation(rotation): return rotation
184185
case let .string(string): return string
186+
case let .font(font): return font
185187
case let .text(text): return text
186188
case let .path(path): return path
187189
case let .mesh(mesh): return mesh
@@ -286,8 +288,8 @@ extension Value {
286288
[.string($0), $1]
287289
})
288290
case .boolean, .vector, .size, .rotation, .color, .texture, .material,
289-
.number, .radians, .halfturns, .string, .text, .path, .mesh, .polygon,
290-
.point, .bounds:
291+
.number, .radians, .halfturns, .string, .font, .text, .path, .mesh,
292+
.polygon, .point, .bounds:
291293
return nil
292294
}
293295
}
@@ -314,7 +316,7 @@ extension Value {
314316
case let .texture(texture):
315317
return texture.map { .texture($0) }
316318
case .boolean, .vector, .size, .rotation, .range, .tuple, .number,
317-
.radians, .halfturns, .string, .text, .path, .material, .mesh,
319+
.radians, .halfturns, .string, .font, .text, .path, .material, .mesh,
318320
.polygon, .point, .bounds, .object:
319321
return nil
320322
}
@@ -327,8 +329,8 @@ extension Value {
327329
case let .texture(texture):
328330
return texture.map { .texture($0) }
329331
case .boolean, .vector, .size, .rotation, .range, .tuple, .color,
330-
.radians, .halfturns, .string, .text, .path, .material, .mesh,
331-
.polygon, .point, .bounds, .object:
332+
.radians, .halfturns, .string, .font, .text, .path, .material,
333+
.mesh, .polygon, .point, .bounds, .object:
332334
return nil
333335
}
334336
}

ShapeScriptTests/StandardLibraryTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,17 @@ final class StandardLibraryTests: XCTestCase {
691691
XCTAssertNoThrow(try program.evaluate(in: context))
692692
}
693693

694+
func testFontNameMember() throws {
695+
let program = try parse("""
696+
font "Times"
697+
print font.name
698+
""")
699+
let delegate = TestDelegate()
700+
let context = EvaluationContext(source: program.source, delegate: delegate)
701+
XCTAssertNoThrow(try program.evaluate(in: context))
702+
XCTAssertEqual(delegate.log, ["Times"])
703+
}
704+
694705
func testFontInBlock() throws {
695706
let program = try parse("""
696707
define foo {

ShapeScriptTests/TypesystemTests.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,39 @@ final class TypesystemTests: XCTestCase {
945945
""", as: .string), .string(url.path))
946946
}
947947

948+
func testCastFontToString() throws {
949+
#if canImport(CoreGraphics)
950+
XCTAssert(Value.font("times").isConvertible(to: .string))
951+
XCTAssertEqual(try evaluate("""
952+
font "EdgeOfTheGalaxyRegular-OVEa6.otf"
953+
define foo font
954+
foo
955+
""", as: .string), .string("Edge of the Galaxy Regular"))
956+
#endif
957+
}
958+
959+
func testCastFontToTexture() throws {
960+
#if canImport(CoreGraphics)
961+
XCTAssertFalse(Value.font("times").isConvertible(to: .texture))
962+
XCTAssertThrowsError(try evaluate("font \"times\"\nfont", as: .texture)) { error in
963+
let error = try? XCTUnwrap(error as? RuntimeError)
964+
XCTAssertEqual(error?.type, .typeMismatch(for: "", index: -1, expected: "texture", got: "font"))
965+
}
966+
#endif
967+
}
968+
969+
func testCastTextureToFont() throws {
970+
#if canImport(CoreGraphics)
971+
let url = TestDelegate().resolveURL(for: "Stars1.jpg")
972+
let texture = Texture.file(name: "Stars1.jpg", url: url, intensity: 1)
973+
XCTAssertFalse(Value.texture(texture).isConvertible(to: .font))
974+
XCTAssertThrowsError(try evaluate("texture \"Stars1.jpg\"\ntexture", as: .font)) { error in
975+
let error = try? XCTUnwrap(error as? RuntimeError)
976+
XCTAssertEqual(error?.type, .typeMismatch(for: "", index: -1, expected: "font", got: "texture"))
977+
}
978+
#endif
979+
}
980+
948981
func testCastPathToMesh() throws {
949982
XCTAssert(Value.path(.square()).isConvertible(to: .mesh))
950983
XCTAssertNotNil(try evaluate("square", as: .mesh))

0 commit comments

Comments
 (0)