Created
November 16, 2020 22:35
-
-
Save hyukhur/fef974284bc14f16d59520d137d2a82c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Color+Additions.swift | |
// EasyDrugs | |
// | |
// Created by Hyuk Hur on 2020-11-16. | |
// | |
import SwiftUI | |
extension Color { | |
init(hex: String, alpha: UInt64 = 255) { | |
let hexString = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) | |
let scanner = Scanner(string: hexString) | |
if (hexString.hasPrefix("#")) { | |
scanner.currentIndex = hexString.index(hexString.startIndex, offsetBy: 1) | |
} | |
var color: UInt64 = 0 | |
Scanner(string: hexString).scanHexInt64(&color) | |
let pattern: HexPattern | |
switch hexString.count { | |
case 3,4: | |
pattern = .rgb | |
case 6,7: | |
pattern = .rrggbb | |
case 8,9: | |
pattern = .aarrggbb | |
default: | |
pattern = .rrggbb | |
} | |
self.init(color, alpha: alpha, pattern: pattern) | |
} | |
enum HexPattern { | |
case rgb // RGB (12-bit) #RGB | |
case rrggbb // RGB (24-bit) #RRGGBB | |
case aarrggbb // ARGB (32-bit) #AARRGGBB | |
func colors(_ hex: UInt64, _ alpha: UInt64) -> (alpha: UInt64, red: UInt64, green: UInt64, blue: UInt64) { | |
switch self { | |
case .rgb: | |
return (alpha, (hex >> 8) * 17, (hex >> 4 & 0xF) * 17, (hex & 0xF) * 17) | |
case .rrggbb: | |
return (alpha, hex >> 16, hex >> 8 & 0xFF, hex & 0xFF) | |
case .aarrggbb: | |
return (hex >> 24, hex >> 16 & 0xFF, hex >> 8 & 0xFF, hex & 0xFF) | |
} | |
} | |
} | |
init(_ hex: UInt64, alpha: UInt64 = 255, pattern: HexPattern = .rrggbb) { | |
let (a, r, g, b) = pattern.colors(hex, alpha) | |
self.init( .sRGB, | |
red: Double(r) / 255, | |
green: Double(g) / 255, | |
blue: Double(b) / 255, | |
opacity: Double(a) / 255 | |
) | |
} | |
/* | |
init(_ hex: UInt64) { | |
let pattern: HexPattern | |
switch hex{ | |
case 0x000...0xFFF: | |
pattern = .rgb | |
case 0x000000...0xFFFFFF: | |
pattern = .rrggbb | |
case 0x00000000...0xFFFFFFFF: | |
pattern = .aarrggbb | |
default: | |
pattern = .rrggbb | |
} | |
self.init(hex, pattern: pattern) | |
} | |
*/ | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ColorTests.swift | |
// EasyDrugsTests | |
// | |
// Created by Hank Hur on 2020-11-16. | |
// | |
import XCTest | |
import SwiftUI | |
import CoreGraphics | |
class ColorTests: XCTestCase { | |
func test12BitHex() throws { | |
let pattern = Color.HexPattern.rgb | |
XCTAssertEqual(Color(0xFFF, pattern: pattern).cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.9999999403953552, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0, pattern: pattern).cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0x8FF, pattern: pattern).cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xF8F, pattern: pattern).cgColor?.components?[1] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFF8, pattern: pattern).cgColor?.components?[2] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFF8, pattern: pattern).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 1, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFF8, alpha: 0, pattern: pattern).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFF8, alpha: 0x8, pattern: pattern).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0.0313725508749485, accuracy: 0.00000001) | |
} | |
func test24BitHex() { | |
let pattern = Color.HexPattern.rrggbb | |
XCTAssertEqual(Color(0xFFFFFF, pattern: pattern).cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.9999999403953552, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0, pattern: pattern).cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0x88FFFF, pattern: pattern).cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFF88FF, pattern: pattern).cgColor?.components?[1] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFFFF88, pattern: pattern).cgColor?.components?[2] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFFFF88, pattern: pattern).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 1, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFFFF88, alpha: 0, pattern: pattern).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFFFF88, alpha: 0x8, pattern: pattern).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0.0313725508749485, accuracy: 0.00000001) | |
} | |
func test32BitHex() { | |
let pattern = Color.HexPattern.aarrggbb | |
XCTAssertEqual(Color(0xFFFFFFFF, pattern: pattern).cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.9999999403953552, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0, pattern: pattern).cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFF88FFFF, pattern: pattern).cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFFFF88FF, pattern: pattern).cgColor?.components?[1] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFFFFFF88, pattern: pattern).cgColor?.components?[2] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0xFFFFFF88, alpha: 0, pattern: pattern).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 1, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0x00FFFF88, alpha: 1, pattern: pattern).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(0x88FFFF88, alpha: 0, pattern: pattern).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
} | |
func test12BitHexString() throws { | |
XCTAssertEqual(Color(hex: "FFF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.9999999403953552, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "000").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "8FF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "F8F").cgColor?.components?[1] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FF8").cgColor?.components?[2] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FF8").cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 1, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FF8", alpha: 0).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FF8", alpha: 0x8).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0.0313725508749485, accuracy: 0.00000001) | |
} | |
func test24BitHexString() { | |
XCTAssertEqual(Color(hex: "FFFFFF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.9999999403953552, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "000000").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "88FFFF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FF88FF").cgColor?.components?[1] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FFFF88").cgColor?.components?[2] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FFFF88").cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 1, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FFFF88", alpha: 0).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FFFF88", alpha: 0x8).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0.0313725508749485, accuracy: 0.00000001) | |
} | |
func test32BitHexString() { | |
XCTAssertEqual(Color(hex: "FFFFFFFF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.9999999403953552, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "00000000").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FF88FFFF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FFFF88FF").cgColor?.components?[1] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FFFFFF88").cgColor?.components?[2] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "FFFFFF88", alpha: 0).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 1, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "00FFFF88", alpha: 1).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "88FFFF88", alpha: 0).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
} | |
func test12BitHexHashString() throws { | |
XCTAssertEqual(Color(hex: "#FFF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.9999999403953552, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#000").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#8FF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#F8F").cgColor?.components?[1] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FF8").cgColor?.components?[2] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FF8").cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 1, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FF8", alpha: 0).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FF8", alpha: 0x8).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0.0313725508749485, accuracy: 0.00000001) | |
} | |
func test24BitHexHashString() { | |
XCTAssertEqual(Color(hex: "#FFFFFF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.9999999403953552, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#000000").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#88FFFF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FF88FF").cgColor?.components?[1] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FFFF88").cgColor?.components?[2] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FFFF88").cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 1, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FFFF88", alpha: 0).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FFFF88", alpha: 0x8).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0.0313725508749485, accuracy: 0.00000001) | |
} | |
func test32BitHexHashString() { | |
XCTAssertEqual(Color(hex: "#FFFFFFFF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.9999999403953552, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#00000000").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FF88FFFF").cgColor?.components?[0] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FFFF88FF").cgColor?.components?[1] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FFFFFF88").cgColor?.components?[2] ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#FFFFFF88", alpha: 0).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 1, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#00FFFF88", alpha: 1).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0, accuracy: 0.00000001) | |
XCTAssertEqual(Color(hex: "#88FFFF88", alpha: 0).cgColor?.alpha ?? CGFloat.greatestFiniteMagnitude, 0.5333333611488342, accuracy: 0.00000001) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment