|
2 | 2 | # ------------------
|
3 | 3 |
|
4 | 4 | # The base type
|
5 |
| -abstract ColorValue |
6 |
| -typealias ColourValue ColorValue |
| 5 | +abstract ColorValue{T} |
| 6 | +typealias ColourValue{T} ColorValue{T} |
7 | 7 |
|
| 8 | +eltype{T}(::ColorValue{T}) = T |
8 | 9 |
|
9 | 10 | # Transparency support
|
10 |
| -immutable AlphaColorValue{T <: ColorValue} |
11 |
| - c::T |
12 |
| - alpha::Float64 |
| 11 | +immutable AlphaColorValue{C <: ColorValue, T <: Number} |
| 12 | + c::C |
| 13 | + alpha::T |
13 | 14 |
|
14 |
| - function AlphaColorValue(x1, x2, x3, alpha=1.0) |
15 |
| - new(T(x1, x2, x3), alpha) |
| 15 | + function AlphaColorValue(x1::T, x2::T, x3::T, alpha::T) |
| 16 | + new(C(x1, x2, x3), alpha) |
16 | 17 | end
|
17 |
| - AlphaColorValue(c::T, alpha=1.0) = new(c, alpha) |
| 18 | + AlphaColorValue(c::C, alpha::T) = new(c, alpha) |
18 | 19 | end
|
19 |
| - |
| 20 | +AlphaColorValue{T<:Fractional}(c::ColorValue{T}, alpha::T = one(T)) = AlphaColorValue{typeof(c),T}(c, alpha) |
20 | 21 |
|
21 | 22 | # sRGB (standard Red-Green-Blue)
|
22 |
| -immutable RGB <: ColorValue |
23 |
| - r::Float64 # Red in [0,1] |
24 |
| - g::Float64 # Green in [0,1] |
25 |
| - b::Float64 # Blue in [0,1] |
| 23 | +immutable RGB{T<:Fractional} <: ColorValue{T} |
| 24 | + r::T # Red [0,1] |
| 25 | + g::T # Green [0,1] |
| 26 | + b::T # Blue [0,1] |
26 | 27 |
|
27 | 28 | function RGB(r::Number, g::Number, b::Number)
|
28 | 29 | new(r, g, b)
|
29 | 30 | end
|
30 | 31 |
|
31 |
| - RGB() = RGB(0, 0, 0) |
32 | 32 | end
|
| 33 | +RGB{T<:Fractional}(r::T, g::T, b::T) = RGB{T}(r, g, b) |
| 34 | +RGB(r, g, b) = (T = promote_type(typeof(r), typeof(g), typeof(b)); RGB{T}(r, g, b)) |
| 35 | +RGB(r::Integer, g::Integer, b::Integer) = RGB{Float64}(r, g, b) |
| 36 | +RGB() = RGB(0.0, 0.0, 0.0) |
33 | 37 |
|
| 38 | +typemin{T}(::Type{RGB{T}}) = RGB{T}(zero(T), zero(T), zero(T)) |
| 39 | +typemax{T}(::Type{RGB{T}}) = RGB{T}(one(T), one(T), one(T)) |
34 | 40 |
|
35 | 41 | # HSV (Hue-Saturation-Value)
|
36 |
| -immutable HSV <: ColorValue |
37 |
| - h::Float64 # Hue in [0,360] |
38 |
| - s::Float64 # Saturation in [0,1] |
39 |
| - v::Float64 # Value in [0,1] |
| 42 | +immutable HSV{T<:FloatingPoint} <: ColorValue{T} |
| 43 | + h::T # Hue in [0,360] |
| 44 | + s::T # Saturation in [0,1] |
| 45 | + v::T # Value in [0,1] |
40 | 46 |
|
41 | 47 | function HSV(h::Number, s::Number, v::Number)
|
42 | 48 | new(h, s, v)
|
43 | 49 | end
|
44 | 50 |
|
45 |
| - HSV() = HSV(0, 0, 0) |
46 | 51 | end
|
| 52 | +HSV{T<:FloatingPoint}(h::T, s::T, v::T) = HSV{T}(h, s, v) |
| 53 | +HSV(h, s, v) = HSV{Float64}(h, s, v) |
| 54 | +HSV() = HSV(0.0, 0.0, 0.0) |
47 | 55 |
|
48 | 56 |
|
49 | 57 | HSB(h, s, b) = HSV(h, s, b)
|
50 | 58 |
|
51 | 59 |
|
52 | 60 | # HSL (Hue-Lightness-Saturation)
|
53 |
| -immutable HSL <: ColorValue |
54 |
| - h::Float64 # Hue in [0,360] |
55 |
| - s::Float64 # Saturation in [0,1] |
56 |
| - l::Float64 # Lightness in [0,1] |
| 61 | +immutable HSL{T<:FloatingPoint} <: ColorValue{T} |
| 62 | + h::T # Hue in [0,360] |
| 63 | + s::T # Saturation in [0,1] |
| 64 | + l::T # Lightness in [0,1] |
57 | 65 |
|
58 | 66 | function HSL(h::Number, s::Number, l::Number)
|
59 | 67 | new(h, s, l)
|
60 | 68 | end
|
61 |
| - |
62 |
| - HSL() = HSL(0, 0, 0) |
63 | 69 | end
|
| 70 | +HSL{T<:FloatingPoint}(h::T, s::T, l::T) = HSL{T}(h, s, l) |
| 71 | +HSL(h, s, l) = HSL{Float64}(h, s, l) |
| 72 | +HSL() = HSL(0.0, 0.0, 0.0) |
64 | 73 |
|
65 | 74 |
|
66 | 75 | HLS(h, l, s) = HSL(h, s, l)
|
67 | 76 |
|
68 | 77 |
|
69 | 78 | # XYZ (CIE 1931)
|
70 |
| -immutable XYZ <: ColorValue |
71 |
| - x::Float64 |
72 |
| - y::Float64 |
73 |
| - z::Float64 |
| 79 | +immutable XYZ{T<:Fractional} <: ColorValue{T} |
| 80 | + x::T |
| 81 | + y::T |
| 82 | + z::T |
74 | 83 |
|
75 | 84 | function XYZ(x::Number, y::Number, z::Number)
|
76 | 85 | new(x, y, z)
|
77 | 86 | end
|
78 |
| - |
79 |
| - XYZ() = XYZ(0, 0, 0) |
80 | 87 | end
|
| 88 | +XYZ{T<:Fractional}(x::T, y::T, z::T) = XYZ{T}(x, y, z) |
| 89 | +XYZ(x, y, z) = (T = promote_type(typeof(x), typeof(y), typeof(z)); XYZ{T}(x, y, z)) |
| 90 | +XYZ() = XYZ(0.0, 0.0, 0.0) |
81 | 91 |
|
82 | 92 | # CIE 1931 xyY (chromaticity + luminance) space
|
83 |
| -immutable xyY <: ColorValue |
84 |
| - x::Float64 |
85 |
| - y::Float64 |
86 |
| - Y::Float64 |
| 93 | +immutable xyY{T<:FloatingPoint} <: ColorValue{T} |
| 94 | + x::T |
| 95 | + y::T |
| 96 | + Y::T |
87 | 97 |
|
88 | 98 | function xyY(x::Number, y::Number, Y::Number)
|
89 | 99 | new(x, y, Y)
|
90 | 100 | end
|
91 |
| - |
92 |
| - xyY() = xyY(0,0,0) |
93 | 101 | end
|
| 102 | +xyY{T<:FloatingPoint}(x::T, y::T, Y::T) = xyY{T}(x, y, Y) |
| 103 | +xyY(x, y, Y) = xyY{Float64}(x, y, Y) |
| 104 | +xyY() = xyY(0.0,0.0,0.0) |
94 | 105 |
|
95 | 106 |
|
96 | 107 | # Lab (CIELAB)
|
97 |
| -immutable Lab <: ColorValue |
98 |
| - l::Float64 # Luminance in approximately [0,100] |
99 |
| - a::Float64 # Red/Green |
100 |
| - b::Float64 # Blue/Yellow |
| 108 | +immutable Lab{T<:FloatingPoint} <: ColorValue{T} |
| 109 | + l::T # Luminance in approximately [0,100] |
| 110 | + a::T # Red/Green |
| 111 | + b::T # Blue/Yellow |
101 | 112 |
|
102 | 113 | function Lab(l::Number, a::Number, b::Number)
|
103 | 114 | new(l, a, b)
|
104 | 115 | end
|
105 |
| - |
106 |
| - Lab() = Lab(0, 0, 0) |
107 | 116 | end
|
| 117 | +Lab{T<:FloatingPoint}(l::T, a::T, b::T) = Lab{T}(l, a, b) |
| 118 | +Lab(l, a, b) = Lab{Float64}(l, a, b) |
| 119 | +Lab() = Lab(0.0, 0.0, 0.0) |
108 | 120 |
|
109 | 121 | typealias LAB Lab
|
110 | 122 |
|
111 | 123 |
|
112 | 124 | # LCHab (Luminance-Chroma-Hue, Polar-Lab)
|
113 |
| -immutable LCHab <: ColorValue |
114 |
| - l::Float64 # Luminance in [0,100] |
115 |
| - c::Float64 # Chroma |
116 |
| - h::Float64 # Hue in [0,360] |
| 125 | +immutable LCHab{T<:FloatingPoint} <: ColorValue{T} |
| 126 | + l::T # Luminance in [0,100] |
| 127 | + c::T # Chroma |
| 128 | + h::T # Hue in [0,360] |
117 | 129 |
|
118 | 130 | function LCHab(l::Number, c::Number, h::Number)
|
119 | 131 | new(l, c, h)
|
120 | 132 | end
|
121 |
| - |
122 |
| - LCHab() = LCHab(0, 0, 0) |
123 | 133 | end
|
| 134 | +LCHab{T<:FloatingPoint}(l::T, c::T, h::T) = LCHab{T}(l, c, h) |
| 135 | +LCHab(l, c, h) = LCHab{Float64}(l, c, h) |
| 136 | +LCHab() = LCHab(0.0, 0.0, 0.0) |
124 | 137 |
|
125 | 138 |
|
126 | 139 | # Luv (CIELUV)
|
127 |
| -immutable Luv <: ColorValue |
128 |
| - l::Float64 # Luminance |
129 |
| - u::Float64 # Red/Green |
130 |
| - v::Float64 # Blue/Yellow |
| 140 | +immutable Luv{T<:FloatingPoint} <: ColorValue{T} |
| 141 | + l::T # Luminance |
| 142 | + u::T # Red/Green |
| 143 | + v::T # Blue/Yellow |
131 | 144 |
|
132 | 145 | function Luv(l::Number, u::Number, v::Number)
|
133 | 146 | new(l, u, v)
|
134 | 147 | end
|
135 |
| - |
136 |
| - Luv() = Luv(0, 0, 0) |
137 | 148 | end
|
| 149 | +Luv{T<:FloatingPoint}(l::T, u::T, v::T) = Luv{T}(l, u, v) |
| 150 | +Luv(l, u, v) = Luv{Float64}(l, u, v) |
| 151 | +Luv() = Luv(0.0, 0.0, 0.0) |
138 | 152 |
|
139 | 153 | typealias LUV Luv
|
140 | 154 |
|
141 | 155 |
|
142 | 156 | # LCHuv (Luminance-Chroma-Hue, Polar-Luv)
|
143 |
| -immutable LCHuv <: ColorValue |
144 |
| - l::Float64 # Luminance |
145 |
| - c::Float64 # Chroma |
146 |
| - h::Float64 # Hue |
| 157 | +immutable LCHuv{T<:FloatingPoint} <: ColorValue{T} |
| 158 | + l::T # Luminance |
| 159 | + c::T # Chroma |
| 160 | + h::T # Hue |
147 | 161 |
|
148 | 162 | function LCHuv(l::Number, c::Number, h::Number)
|
149 | 163 | new(l, c, h)
|
150 | 164 | end
|
151 |
| - |
152 |
| - LCHuv() = LCHuv(0, 0, 0) |
153 | 165 | end
|
| 166 | +LCHuv{T<:FloatingPoint}(l::T, c::T, h::T) = LCHuv{T}(l, c, h) |
| 167 | +LCHuv(l, c, h) = LCHuv{Float64}(l, c, h) |
| 168 | +LCHuv() = LCHuv(0.0, 0.0, 0.0) |
154 | 169 |
|
155 | 170 |
|
156 | 171 | # DIN99 (L99, a99, b99) - adaptation of CIELAB
|
157 |
| -immutable DIN99 <: ColorValue |
158 |
| - l::Float64 # L99 |
159 |
| - a::Float64 # a99 |
160 |
| - b::Float64 # b99 |
| 172 | +immutable DIN99{T<:FloatingPoint} <: ColorValue{T} |
| 173 | + l::T # L99 |
| 174 | + a::T # a99 |
| 175 | + b::T # b99 |
161 | 176 |
|
162 | 177 | function DIN99(l::Number, a::Number, b::Number)
|
163 | 178 | new(l, a, b)
|
164 | 179 | end
|
165 |
| - |
166 |
| - DIN99() = DIN99(0, 0, 0) |
167 | 180 | end
|
| 181 | +DIN99{T<:FloatingPoint}(l::T, a::T, b::T) = DIN99{T}(l, a, b) |
| 182 | +DIN99(l, a, b) = DIN99{Float64}(l, a, b) |
| 183 | +DIN99() = DIN99(0.0, 0.0, 0.0) |
168 | 184 |
|
169 | 185 |
|
170 | 186 | # DIN99d (L99d, a99d, b99d) - Improvement on DIN99
|
171 |
| -immutable DIN99d <: ColorValue |
172 |
| - l::Float64 # L99d |
173 |
| - a::Float64 # a99d |
174 |
| - b::Float64 # b99d |
| 187 | +immutable DIN99d{T<:FloatingPoint} <: ColorValue{T} |
| 188 | + l::T # L99d |
| 189 | + a::T # a99d |
| 190 | + b::T # b99d |
175 | 191 |
|
176 | 192 | function DIN99d(l::Number, a::Number, b::Number)
|
177 | 193 | new(l, a, b)
|
178 | 194 | end
|
179 |
| - |
180 |
| - DIN99d() = DIN99d(0, 0, 0) |
181 | 195 | end
|
| 196 | +DIN99d{T<:FloatingPoint}(l::T, a::T, b::T) = DIN99d{T}(l, a, b) |
| 197 | +DIN99d(l, a, b) = DIN99{Float64}(l, a, b) |
| 198 | +DIN99d() = DIN99d(0.0, 0.0, 0.0) |
182 | 199 |
|
183 | 200 |
|
184 | 201 | # DIN99o (L99o, a99o, b99o) - adaptation of CIELAB
|
185 |
| -immutable DIN99o <: ColorValue |
186 |
| - l::Float64 # L99o |
187 |
| - a::Float64 # a99o |
188 |
| - b::Float64 # b99o |
| 202 | +immutable DIN99o{T<:FloatingPoint} <: ColorValue{T} |
| 203 | + l::T # L99o |
| 204 | + a::T # a99o |
| 205 | + b::T # b99o |
189 | 206 |
|
190 | 207 | function DIN99o(l::Number, a::Number, b::Number)
|
191 | 208 | new(l, a, b)
|
192 | 209 | end
|
193 |
| - |
194 |
| - DIN99o() = DIN99o(0, 0, 0) |
195 | 210 | end
|
| 211 | +DIN99o{T<:FloatingPoint}(l::T, a::T, b::T) = DIN99o{T}(l, a, b) |
| 212 | +DIN99o(l, a, b) = DIN99o{Float64}(l, a, b) |
| 213 | +DIN99o() = DIN99o(0.0, 0.0, 0.0) |
196 | 214 |
|
197 | 215 |
|
198 | 216 | # LMS (Long Medium Short)
|
199 |
| -immutable LMS <: ColorValue |
200 |
| - l::Float64 # Long |
201 |
| - m::Float64 # Medium |
202 |
| - s::Float64 # Short |
| 217 | +immutable LMS{T<:FloatingPoint} <: ColorValue{T} |
| 218 | + l::T # Long |
| 219 | + m::T # Medium |
| 220 | + s::T # Short |
203 | 221 |
|
204 | 222 | function LMS(l::Number, m::Number, s::Number)
|
205 | 223 | new(l, m, s)
|
206 | 224 | end
|
207 |
| - |
208 |
| - LMS() = LMS(0, 0, 0) |
209 | 225 | end
|
| 226 | +LMS{T<:FloatingPoint}(l::T, m::T, s::T) = LMS{T}(l, m, s) |
| 227 | +LMS(l, m, s) = LMS{Float64}(l, m, s) |
| 228 | +LMS() = LMS(0.0, 0.0, 0.0) |
210 | 229 |
|
211 | 230 |
|
212 | 231 | # 24 bit RGB (used by Cairo)
|
213 |
| -immutable RGB24 <: ColorValue |
| 232 | +immutable RGB24 <: ColorValue{Uint8} |
214 | 233 | color::Uint32
|
215 | 234 |
|
216 | 235 | RGB24(c::Unsigned) = new(c)
|
217 | 236 | RGB24() = RGB24(0)
|
218 | 237 | end
|
219 | 238 |
|
| 239 | +AlphaColorValue(c::RGB24, alpha::Uint8 = 0xff) = AlphaColorValue{typeof(c),Uint8}(c, alpha) |
220 | 240 |
|
221 | 241 | # Versions with transparency
|
222 |
| -typealias RGBA AlphaColorValue{RGB} |
223 |
| -typealias HSVA AlphaColorValue{HSV} |
224 |
| -typealias HSLA AlphaColorValue{HSL} |
225 |
| -typealias XYZA AlphaColorValue{XYZ} |
226 |
| -typealias xyYA AlphaColorValue{xyY} |
227 |
| -typealias LabA AlphaColorValue{Lab} |
228 |
| -typealias LCHabA AlphaColorValue{LCHab} |
229 |
| -typealias LuvA AlphaColorValue{Luv} |
230 |
| -typealias LCHuvA AlphaColorValue{LCHuv} |
231 |
| -typealias DIN99A AlphaColorValue{DIN99} |
232 |
| -typealias DIN99dA AlphaColorValue{DIN99d} |
233 |
| -typealias DIN99oA AlphaColorValue{DIN99o} |
234 |
| -typealias LMSA AlphaColorValue{LMS} |
235 |
| -typealias RGBA32 AlphaColorValue{RGB24} |
| 242 | +typealias RGBA{T} AlphaColorValue{RGB{T},T} |
| 243 | +typealias HSVA{T} AlphaColorValue{HSV{T},T} |
| 244 | +typealias HSLA{T} AlphaColorValue{HSL{T},T} |
| 245 | +typealias XYZA{T} AlphaColorValue{XYZ{T},T} |
| 246 | +typealias xyYA{T} AlphaColorValue{xyY{T},T} |
| 247 | +typealias LabA{T} AlphaColorValue{Lab{T},T} |
| 248 | +typealias LCHabA{T} AlphaColorValue{LCHab{T},T} |
| 249 | +typealias LuvA{T} AlphaColorValue{Luv{T},T} |
| 250 | +typealias LCHuvA{T} AlphaColorValue{LCHuv{T},T} |
| 251 | +typealias DIN99A{T} AlphaColorValue{DIN99{T},T} |
| 252 | +typealias DIN99dA{T} AlphaColorValue{DIN99d{T},T} |
| 253 | +typealias DIN99oA{T} AlphaColorValue{DIN99o{T},T} |
| 254 | +typealias LMSA{T} AlphaColorValue{LMS{T},T} |
| 255 | +typealias RGBA32 AlphaColorValue{RGB24,Uint8} |
| 256 | + |
| 257 | +rgba{T}(c::ColorValue{T}) = AlphaColorValue(convert(RGB{T},c)) |
| 258 | +hsva{T}(c::ColorValue{T}) = AlphaColorValue(convert(HSV{T},c)) |
| 259 | +hsla{T}(c::ColorValue{T}) = AlphaColorValue(convert(HSL{T},c)) |
| 260 | +xyza{T}(c::ColorValue{T}) = AlphaColorValue(convert(XYZ{T},c)) |
| 261 | +xyYa{T}(c::ColorValue{T}) = AlphaColorValue(convert(xyY{T},c)) |
| 262 | +laba{T}(c::ColorValue{T}) = AlphaColorValue(convert(Lab{T},c)) |
| 263 | +lchaba{T}(c::ColorValue{T}) = AlphaColorValue(convert(LCH{T},c)) |
| 264 | +luva{T}(c::ColorValue{T}) = AlphaColorValue(convert(Luv{T},c)) |
| 265 | +lchuva{T}(c::ColorValue{T}) = AlphaColorValue(convert(LCHuv{T},c)) |
| 266 | +din99a{T}(c::ColorValue{T}) = AlphaColorValue(convert(DIN99{T},c)) |
| 267 | +din99da{T}(c::ColorValue{T}) = AlphaColorValue(convert(DIN99d{T},c)) |
| 268 | +din99oa{T}(c::ColorValue{T}) = AlphaColorValue(convert(DIN99o{T},c)) |
| 269 | +lmsa{T}(c::ColorValue{T}) = AlphaColorValue(convert(LMS{T},c)) |
| 270 | +rgba32{T}(c::ColorValue{T}) = AlphaColorValue(convert(RGB24,c)) |
| 271 | + |
| 272 | +const CVparametric = (RGB, HSV, HSL, XYZ, xyY, Lab, Luv, LCHab, LCHuv, DIN99, DIN99d, DIN99o, LMS) |
0 commit comments