Skip to content

Commit

Permalink
Update to SwiftSCAD 0.8.1 and Swift 6
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasf committed Nov 1, 2024
1 parent d030bd2 commit 285cca2
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 32 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
*.xcuserstate
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/tomasf/SwiftSCAD.git",
"state" : {
"revision" : "d874d042c45046f1f87b4e27bc27ddd292fa874a",
"version" : "0.7.1"
"revision" : "06d0fa1ee58b340ce288ded167e91dda02e11119",
"version" : "0.8.1"
}
}
],
Expand Down
15 changes: 7 additions & 8 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.
// swift-tools-version: 6.0

import PackageDescription

let package = Package(
name: "RichText",
platforms: [.macOS(.v14)],
platforms: [.macOS(.v13)],
products: [
.library(name: "RichText", targets: ["RichText"]),
],
dependencies: [
.package(url: "https://github.com/tomasf/SwiftSCAD.git", from: "0.7.1"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"),
.package(url: "https://github.com/tomasf/SwiftSCAD.git", .upToNextMinor(from: "0.8.1")),
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.1"),
],
targets: [
.target(name: "RichText", dependencies: [
"SwiftSCAD",
.product(name: "Logging", package: "swift-log")
]),
.product(name: "SwiftSCAD", package: "SwiftSCAD"),
.product(name: "Logging", package: "swift-log"),
])
]
)
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,16 @@
RichText is a macOS-specific companion library for SwiftSCAD that adds TextKit-based text generation. This enables proper Unicode support, richer typography, attribute ranges, multi-line text, constrained layout, bounding boxes, glyph-level manipulation and more.

This package also contains a `Geometry2D` extension for `CGPath` that can be used for other Core Graphics-related purposes.

<pre>
let package = Package(
name: "thingamajig",
dependencies: [
.package(url: "https://github.com/tomasf/SwiftSCAD.git", .upToNextMinor(from: "0.8.1")),
<b><i>.package(url: "https://github.com/tomasf/RichText.git", from: "0.1.0")</i></b>
],
targets: [
.executableTarget(name: "thingamajig", dependencies: ["SwiftSCAD", <b><i>"RichText"</i></b>])
]
)
</pre>
3 changes: 2 additions & 1 deletion Sources/RichText/Environment/Environment+FillRule.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import Foundation
import SwiftSCAD
import QuartzCore
@preconcurrency import QuartzCore

extension CGPath {
static internal let fillRuleEnvironmentKey: Environment.ValueKey = .init(rawValue: "CGPath.FillRule")
}


public extension Environment {
var cgPathFillRule: CGPathFillRule {
(self[CGPath.fillRuleEnvironmentKey] as? CGPathFillRule) ?? .evenOdd
Expand Down
4 changes: 2 additions & 2 deletions Sources/RichText/Environment/Environment+RichText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public extension Geometry2D {
withEnvironment { $0.withBaselineAlignment(alignment) }
}

func usingTextAttribute<K: AttributedStringKey>(_ key: K.Type, value: K.Value?) -> any Geometry2D {
func usingTextAttribute<K: AttributedStringKey>(_ key: K.Type, value: K.Value?) -> any Geometry2D where K.Value: Sendable {
withEnvironment { environment in
var container = environment.textAttributeContainer
container[K.self] = value
Expand All @@ -64,7 +64,7 @@ public extension Geometry3D {
withEnvironment { $0.withBaselineAlignment(alignment) }
}

func usingTextAttribute<K: AttributedStringKey>(_ key: K.Type, value: K.Value?) -> any Geometry3D {
func usingTextAttribute<K: AttributedStringKey>(_ key: K.Type, value: K.Value?) -> any Geometry3D where K.Value: Sendable {
withEnvironment { environment in
var container = environment.textAttributeContainer
container[K.self] = value
Expand Down
6 changes: 3 additions & 3 deletions Sources/RichText/Extensions/Geometry2D+CGPath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import QuartzCore

extension QuartzCore.CGPath: SwiftSCAD.Shape2D {
public var body: any Geometry2D {
EnvironmentReader { environment in
self.componentsSeparated(using: environment.cgPathFillRule).map { component in
let (positive, negatives) = component.normalizedPolygons(using: environment.cgPathFillRule)
readEnvironment(\.cgPathFillRule) { fillRule in
self.componentsSeparated(using: fillRule).map { component in
let (positive, negatives) = component.normalizedPolygons(using: fillRule)
return positive.subtracting { negatives }
}
}
Expand Down
32 changes: 16 additions & 16 deletions Sources/RichText/RichText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ public struct RichText: Shape2D {
internal let text: AttributedString
internal let layout: Layout

@EnvironmentValue(\.self) var environment
@EnvironmentValue(\.textBoundaryType) var textBoundaryType

public init(_ text: AttributedString, layout: Layout = .free) {
self.text = text
self.layout = layout
Expand All @@ -15,26 +18,23 @@ public struct RichText: Shape2D {
}

public var body: any Geometry2D {
EnvironmentReader { environment in
let lineFragments = lineFragments(in: environment)
let lineFragments = lineFragments(in: environment)

Union {
for fragment in lineFragments {
for glyph in fragment.glyphs {
glyph.shape.translated(glyph.location)
}
}
}
.modifyingBounds { box in
environment.textBoundaryType == .shape ? box :
.init(union: lineFragments.map(\.glyphBox))
lineFragments.map {
$0.glyphs.map { $0.shape.translated($0.location) }
}
.modifyingBounds { box in
if let box, textBoundaryType == .shape {
box
} else {
.init(union: lineFragments.map(\.glyphBox))
}
.usingCGPathFillRule(.winding)
}
.usingCGPathFillRule(.winding)
}

public func readingLineFragments(@UnionBuilder2D _ reader: @escaping ([LineFragment]) -> any Geometry2D) -> any Geometry2D {
EnvironmentReader { environment in
readEnvironment { environment in
reader(lineFragments(in: environment))
.usingCGPathFillRule(.winding)
}
Expand Down Expand Up @@ -73,12 +73,12 @@ public extension RichText {
}
}

enum BaselineAlignment {
enum BaselineAlignment: Sendable {
case first
case last
}

enum BoundaryType {
enum BoundaryType: Sendable {
case shape
case lineFragments
}
Expand Down

0 comments on commit 285cca2

Please sign in to comment.