Skip to content

Commit 17c4e5e

Browse files
committed
Support Current Color
1 parent 3fe4bca commit 17c4e5e

File tree

10 files changed

+74
-29
lines changed

10 files changed

+74
-29
lines changed

SwiftDraw/DOM.Color.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extension DOM {
3333

3434
enum Color: Equatable {
3535
case none
36+
case currentColor
3637
case keyword(Keyword)
3738
case rgbi(UInt8, UInt8, UInt8)
3839
case rgbf(DOM.Float, DOM.Float, DOM.Float)

SwiftDraw/DOM.Element.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ protocol ContainerElement {
3838
protocol PresentationAttributes {
3939
var opacity: DOM.Float? { get set }
4040
var display: DOM.DisplayMode? { get set }
41-
41+
var color: DOM.Color? { get set }
42+
4243
var stroke: DOM.Color? { get set }
4344
var strokeWidth: DOM.Float? { get set }
4445
var strokeOpacity: DOM.Float? { get set }
@@ -67,7 +68,8 @@ extension DOM {
6768

6869
var opacity: DOM.Float?
6970
var display: DOM.DisplayMode?
70-
71+
var color: DOM.Color?
72+
7173
var stroke: DOM.Color?
7274
var strokeWidth: DOM.Float?
7375
var strokeOpacity: DOM.Float?

SwiftDraw/Image.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,13 @@ extension DOM.SVG {
108108
public extension Image {
109109

110110
convenience init?(fileURL url: URL) {
111-
guard let svg = try? DOM.SVG.parse(fileURL: url) else {
111+
do {
112+
let svg = try DOM.SVG.parse(fileURL: url)
113+
self.init(svg: svg)
114+
} catch {
115+
print("[swiftdraw]", "parsing error", error)
112116
return nil
113117
}
114-
115-
self.init(svg: svg)
116118
}
117119

118120
convenience init?(named name: String, in bundle: Bundle = Bundle.main) {

SwiftDraw/LayerTree.Builder.swift

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,9 @@ extension LayerTree.Builder {
157157
let stroke: LayerTree.Color
158158

159159
if state.strokeWidth > 0.0 {
160-
stroke = LayerTree.Color.create(from: state.stroke).withAlpha(state.strokeOpacity).maybeNone()
160+
stroke = LayerTree.Color
161+
.create(from: state.stroke, current: state.color)
162+
.withAlpha(state.strokeOpacity).maybeNone()
161163
} else {
162164
stroke = .none
163165
}
@@ -170,7 +172,9 @@ extension LayerTree.Builder {
170172
}
171173

172174
func makeFillAttributes(with state: State) -> LayerTree.FillAttributes {
173-
let fill = LayerTree.Color.create(from: state.fill.makeColor()).withAlpha(state.fillOpacity).maybeNone()
175+
let fill = LayerTree.Color
176+
.create(from: state.fill.makeColor(), current: state.color)
177+
.withAlpha(state.fillOpacity).maybeNone()
174178

175179
if case .url(let patternId) = state.fill,
176180
let element = svg.defs.patterns.first(where: { $0.id == patternId.fragment }) {
@@ -186,7 +190,9 @@ extension LayerTree.Builder {
186190
}
187191

188192
static func makeTextAttributes(with state: State) -> LayerTree.TextAttributes {
189-
let fill = LayerTree.Color.create(from: state.fill.makeColor()).withAlpha(state.fillOpacity).maybeNone()
193+
let fill = LayerTree.Color
194+
.create(from: state.fill.makeColor(), current: state.color)
195+
.withAlpha(state.fillOpacity).maybeNone()
190196
return LayerTree.TextAttributes(
191197
color: fill,
192198
fontName: state.fontFamily,
@@ -232,7 +238,7 @@ extension LayerTree.Builder {
232238
func makeGradientStops(for element: DOM.LinearGradient) -> [LayerTree.Gradient.Stop] {
233239
return element.stops.map {
234240
LayerTree.Gradient.Stop(offset: $0.offset,
235-
color: LayerTree.Color($0.color),
241+
color: LayerTree.Color.create(from: $0.color, current: .none),
236242
opacity: $0.opacity)
237243
}
238244
}
@@ -241,6 +247,7 @@ extension LayerTree.Builder {
241247
struct State {
242248
var opacity: DOM.Float
243249
var display: DOM.DisplayMode
250+
var color: DOM.Color
244251

245252
var stroke: DOM.Color
246253
var strokeWidth: DOM.Float
@@ -261,6 +268,7 @@ extension LayerTree.Builder {
261268
//default root SVG element state
262269
opacity = 1.0
263270
display = .inline
271+
color = .keyword(.black)
264272

265273
stroke = .none
266274
strokeWidth = 1.0
@@ -284,6 +292,7 @@ extension LayerTree.Builder {
284292

285293
state.opacity = attributes.opacity ?? 1.0
286294
state.display = attributes.display ?? existing.display
295+
state.color = attributes.color ?? existing.color
287296

288297
state.stroke = attributes.stroke ?? existing.stroke
289298
state.strokeWidth = attributes.strokeWidth ?? existing.strokeWidth
@@ -297,7 +306,7 @@ extension LayerTree.Builder {
297306
state.fillRule = attributes.fillRule ?? existing.fillRule
298307

299308
state.fontFamily = attributes.fontFamily ?? existing.fontFamily
300-
state.fontSize = attributes.fontSize ?? existing.fontSize
309+
state.fontSize = attributes.fontSize ?? existing.fontSize
301310

302311
return state
303312
}

SwiftDraw/LayerTree.Color.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,13 @@ extension LayerTree {
4848
}
4949

5050
extension LayerTree.Color {
51-
52-
init(_ color: DOM.Color) {
53-
self = LayerTree.Color.create(from: color)
54-
}
55-
56-
static func create(from color: DOM.Color) -> LayerTree.Color {
51+
52+
static func create(from color: DOM.Color, current: DOM.Color) -> LayerTree.Color {
5753
switch(color){
5854
case .none:
5955
return .none
56+
case .currentColor:
57+
return create(from: current, current: .none)
6058
case let .keyword(c):
6159
let rgbi = c.rgbi
6260
return LayerTree.Color(rgbi.0, rgbi.1, rgbi.2)

SwiftDraw/Parser.XML.Color.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ extension XMLParser {
3939
return .color(c)
4040
} else if let c = try parseColorP3(data: data) {
4141
return .color(c)
42+
} else if let c = parseCurrentColor(data: data) {
43+
return .color(c)
4244
} else if let c = parseColorKeyword(data: data) {
4345
return .color(c)
4446
} else if let c = parseColorNone(data: data) {
@@ -58,7 +60,15 @@ extension XMLParser {
5860
}
5961
return nil
6062
}
61-
63+
64+
private func parseCurrentColor(data: String) -> DOM.Color? {
65+
let raw = data.trimmingCharacters(in: .whitespaces)
66+
guard raw == "currentColor" else {
67+
return nil
68+
}
69+
return .currentColor
70+
}
71+
6272
private func parseColorKeyword(data: String) -> DOM.Color? {
6373
let raw = data.trimmingCharacters(in: .whitespaces)
6474
guard let keyword = DOM.Color.Keyword(rawValue: raw) else {

SwiftDraw/Parser.XML.Element.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,8 @@ extension XMLParser {
216216

217217
el.opacity = try att.parsePercentage("opacity")
218218
el.display = try att.parseRaw("display")
219-
219+
el.color = try att.parseColor("color")
220+
220221
el.stroke = try att.parseColor("stroke")
221222
el.strokeWidth = try att.parseFloat("stroke-width")
222223
el.strokeOpacity = try att.parsePercentage("stroke-opacity")
@@ -262,6 +263,7 @@ extension PresentationAttributes {
262263
mutating func updateAttributes(from attributes: PresentationAttributes) {
263264
opacity = attributes.opacity
264265
display = attributes.display
266+
color = attributes.color
265267
stroke = attributes.stroke
266268
strokeWidth = attributes.strokeWidth
267269
strokeOpacity = attributes.strokeOpacity

SwiftDraw/XML.SAXParser.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ extension XML {
3939
final class SAXParser: NSObject, XMLParserDelegate {
4040

4141
#if canImport(FoundationXML)
42-
typealias XMLParser = FoundationXML.XMLParser
42+
typealias FoundationXMLParser = FoundationXML.XMLParser
4343
#else
44-
typealias XMLParser = Foundation.XMLParser
44+
typealias FoundationXMLParser = Foundation.XMLParser
4545
#endif
4646

47-
private let parser: XMLParser
47+
private let parser: FoundationXMLParser
4848
private let namespaceURI = "http://www.w3.org/2000/svg"
4949

5050
private var rootNode: Element?
@@ -55,7 +55,7 @@ extension XML {
5555
}
5656

5757
private init(data: Data) {
58-
self.parser = XMLParser(data: data)
58+
self.parser = FoundationXMLParser(data: data)
5959
elements = [Element]()
6060
super.init()
6161

@@ -69,7 +69,7 @@ extension XML {
6969
guard
7070
parser.parser.parse(),
7171
let rootNode = parser.rootNode else {
72-
let error = parser.parser.parserError ?? SwiftDraw.XMLParser.Error.invalid
72+
let error = parser.parser.parserError ?? XMLParser.Error.invalid
7373
throw error
7474
}
7575

@@ -81,7 +81,7 @@ extension XML {
8181
return try parse(data: data)
8282
}
8383

84-
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName _: String?, attributes attributeDict: [String: String] = [:]) {
84+
func parser(_ parser: FoundationXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName _: String?, attributes attributeDict: [String: String] = [:]) {
8585
guard
8686
self.parser === parser,
8787
namespaceURI == self.namespaceURI else {
@@ -99,7 +99,7 @@ extension XML {
9999
}
100100
}
101101

102-
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName _: String?) {
102+
func parser(_ parser: FoundationXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName _: String?) {
103103
guard
104104
namespaceURI == self.namespaceURI,
105105
currentElement.name == elementName else {
@@ -109,7 +109,7 @@ extension XML {
109109
elements.removeLast()
110110
}
111111

112-
func parser(_ parser: XMLParser, foundCharacters string: String) {
112+
func parser(_ parser: FoundationXMLParser, foundCharacters string: String) {
113113
guard let element = elements.last else { return }
114114
let text = element.innerText.map { $0.appending(string) }
115115
element.innerText = text ?? string

SwiftDrawTests/LayerTree.ColorTests.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,26 @@ final class LayerTreeColorTests: XCTestCase {
130130
XCTAssertEqual(Color(green), .srgb(r: 0.0, g: 1.0, b: 0.0, a: 1.0))
131131
XCTAssertEqual(Color(blue), .srgb(r: 0.0, g: 0.0, b: 1.0, a: 1.0))
132132
}
133-
133+
134+
func testCurrentColor() {
135+
// DOM.Color converts correctly
136+
137+
let none = DOM.Color.none
138+
let black = DOM.Color.keyword(.black)
139+
let white = DOM.Color.keyword(.white)
140+
141+
XCTAssertEqual(Color.create(from: .currentColor, current: none), .none)
142+
XCTAssertEqual(Color.create(from: .currentColor, current: black), Color(black))
143+
XCTAssertEqual(Color.create(from: .currentColor, current: white), Color(white))
144+
}
134145
}
135146

136147
extension LayerTree.Color {
137-
148+
149+
init(_ color: DOM.Color) {
150+
self = LayerTree.Color.create(from: color, current: .none)
151+
}
152+
138153
static func srgb(r: LayerTree.Float,
139154
g: LayerTree.Float,
140155
b: LayerTree.Float,

SwiftDrawTests/Parser.XML.ColorTests.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,13 @@ final class ParserColorTests: XCTestCase {
3939
XCTAssertEqual(try XMLParser().parseColor(" none"), .none)
4040
XCTAssertEqual(try XMLParser().parseColor("\t none \t"), .none)
4141
}
42-
42+
43+
func testColorCurrent() {
44+
XCTAssertEqual(try XMLParser().parseColor("currentColor"), .currentColor)
45+
XCTAssertEqual(try XMLParser().parseColor(" currentColor"), .currentColor)
46+
XCTAssertEqual(try XMLParser().parseColor("\t currentColor \t"), .currentColor)
47+
}
48+
4349
func testColorKeyword() {
4450
XCTAssertEqual(try XMLParser().parseColor("aliceblue"), .keyword(.aliceblue))
4551
XCTAssertEqual(try XMLParser().parseColor("wheat"), .keyword(.wheat))

0 commit comments

Comments
 (0)