-
Notifications
You must be signed in to change notification settings - Fork 6
/
X11Colors.swift
155 lines (115 loc) · 4.77 KB
/
X11Colors.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//
// X11ColorList.swift
// BitmapCanvas
//
// Created by nst on 28/02/16.
// Copyright © 2016 Nicolas Seriot. All rights reserved.
//
import Cocoa
extension NSRegularExpression {
class func findAll(string s: String, pattern: String) throws -> [String] {
let regex = try NSRegularExpression(pattern: pattern, options: [])
let matches = regex.matches(in: s, options: [], range: NSMakeRange(0, s.count))
var results : [String] = []
for m in matches {
for i in 1..<m.numberOfRanges {
let range = m.range(at: i)
results.append((s as NSString).substring(with: range))
}
}
return results
}
}
protocol ConvertibleToNSColor {
var color : NSColor { get }
}
extension NSColor : ConvertibleToNSColor {
var color : NSColor {
return self
}
}
extension UInt32 : ConvertibleToNSColor {
var color : NSColor {
let r = Double((self >> 16) & 0xff) / 255.0
let g = Double((self >> 08) & 0xff) / 255.0
let b = Double((self >> 00) & 0xff) / 255.0
return NSColor(calibratedRed:r.cgFloat, green:g.cgFloat, blue:b.cgFloat, alpha:1.0)
}
}
extension String : ConvertibleToNSColor {
var color : NSColor {
let scanner = Scanner(string: self)
if scanner.scanString("#", into: nil) {
var result : UInt32 = 0
if scanner.scanHexInt32(&result) {
return result.color
} else {
assertionFailure("cannot convert \(self) to hex color)")
return NSColor.clear
}
}
if let c = X11Colors.sharedInstance.colorList.color(withKey: self.lowercased()) {
return c
}
assertionFailure("cannot convert \(self) into color)")
return NSColor.clear
}
}
extension NSColor {
convenience init(_ r:Int, _ g:Int, _ b:Int, _ a:Int = 255) {
self.init(
calibratedRed: CGFloat(r)/255.0,
green: CGFloat(g)/255.0,
blue: CGFloat(b)/255.0,
alpha: CGFloat(a)/255.0)
}
class var randomColor : NSColor {
return C(Int(arc4random_uniform(256)), Int(arc4random_uniform(256)), Int(arc4random_uniform(256)))
}
class func rainbowColor(offset: Double = 0.0, percent pct: Double = 0.0, alpha: Double = 1.0) -> NSColor {
let red = sin(2 * Double.pi * (offset + pct) + 0) * 0.5 + 0.5
let green = sin(2 * Double.pi * (offset + pct) + 2) * 0.5 + 0.5
let blue = sin(2 * Double.pi * (offset + pct) + 4) * 0.5 + 0.5
return NSColor(
calibratedRed: red.cgFloat,
green: green.cgFloat,
blue: blue.cgFloat,
alpha: alpha.cgFloat
)
}
}
func C(_ r:Int, _ g:Int, _ b:Int, _ a:Int = 255) -> NSColor {
return NSColor(r,g,b,a)
}
func C(_ r:CGFloat, _ g:CGFloat, _ b:CGFloat, _ a:CGFloat = 255.0) -> NSColor {
return NSColor(calibratedRed: r, green: g, blue: b, alpha: a)
}
class X11Colors {
static let sharedInstance = X11Colors(namePrettifier: { $0.lowercased() })
var colorList = NSColorList(name: "X11")
init(path:String = "/opt/X11/share/X11/rgb.txt", namePrettifier:@escaping (_ original:String) -> (String)) {
let contents = try! String(contentsOfFile: path, encoding: String.Encoding.utf8)
contents.enumerateLines { (line, stop) in
let pattern = "\\s?+(\\d+?)\\s+(\\d+?)\\s+(\\d+?)\\s+(\\w+)$"
let matches = try! NSRegularExpression.findAll(string: line, pattern: pattern)
if matches.count != 4 { return } // ignore names with white spaces, they also appear in camel case
let r = CGFloat(Int(matches[0])!)
let g = CGFloat(Int(matches[1])!)
let b = CGFloat(Int(matches[2])!)
let name = matches[3]
let prettyName = namePrettifier(name)
let color = NSColor(calibratedRed: r/255.0, green: g/255.0, blue: b/255.0, alpha: 1.0)
self.colorList.setColor(color, forKey: prettyName)
//print("\(name) \t -> \t \(prettyName)")
}
}
static func dump(_ inPath:String, outPath:String) -> Bool {
let x11Colors = X11Colors(namePrettifier: {
let name = ($0 as NSString)
let firstCharacter = name.substring(to: 1)
let restOfString = name.substring(with: NSMakeRange(1, name.lengthOfBytes(using: String.Encoding.utf8.rawValue)-1))
return "\(firstCharacter.uppercased())\(restOfString)"
})
return x11Colors.colorList.write(toFile: outPath)
}
}