Parse hsv colors

This commit is contained in:
Sven Weidauer 2021-01-01 13:49:44 +01:00
parent 0b94872101
commit 75a3bc265d
2 changed files with 80 additions and 1 deletions

View file

@ -31,9 +31,58 @@ extension Scanner {
return Color(white: arguments) return Color(white: arguments)
} }
if string("hsva") {
return readHSV(alpha: true)
}
if string("hsv") {
return readHSV(alpha: false)
}
return nil return nil
} }
private func readHSV(alpha readAlpha: Bool) -> Color? {
guard
string("("),
let hue = degrees(),
string(","),
let saturation = component(),
string(","),
let value = component()
else { return nil }
let alpha: UInt8
if readAlpha {
guard
string(","),
let value = component()
else { return nil }
alpha = value
} else {
alpha = 0xFF
}
guard string(")") else { return nil }
return Color(hue: hue, saturation: saturation, value: value, alpha: alpha)
}
func degrees() -> Int? {
guard let int = scanInt() else { return nil }
if string("%") {
guard 0...100 ~= int else { return nil }
return (360 * int) / 100
} else if string("°") || string("deg") {
return int
} else {
guard 0...0xFF ~= int else { return nil }
return (360 * int) / 0xFF
}
}
func colorReference() -> String? { func colorReference() -> String? {
guard string("@") else { return nil } guard string("@") else { return nil }
return name() return name()

View file

@ -86,8 +86,38 @@ final class ColorParserTest: XCTestCase {
XCTAssertTrue(scanner.isAtEnd) XCTAssertTrue(scanner.isAtEnd)
} }
func testScanningDegreesAsByte() throws {
let scanner = Scanner(string: "128")
XCTAssertEqual(scanner.degrees(), 180)
}
func testScanningDegreesAsPercentage() throws {
let scanner = Scanner(string: "50%")
XCTAssertEqual(scanner.degrees(), 180)
}
func testScanningDegrees() throws {
let scanner = Scanner(string: "120°")
XCTAssertEqual(scanner.degrees(), 120)
}
func testScanningDegreesWithDegSuffix() throws {
let scanner = Scanner(string: "120 deg")
XCTAssertEqual(scanner.degrees(), 120)
}
func testScanningHSVColor() throws {
XCTAssertEqual(scanColor("hsv(60°, 255, 100%)"), Color(red: 0xFF, green: 0xFF, blue: 0))
}
func testScanningHSVAColor() throws {
XCTAssertEqual(scanColor("hsva(60°, 50%, 255, 99)"), Color(red: 0xFF, green: 0xFF, blue: 128, alpha: 99))
}
private func scanColor(_ input: String) -> Color? { private func scanColor(_ input: String) -> Color? {
let scanner = Scanner(string: input) let scanner = Scanner(string: input)
return scanner.color() let result = scanner.color()
XCTAssertTrue(result == nil || scanner.isAtEnd)
return result
} }
} }