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