spectrum 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +93 -0
- data/Install.txt +18 -0
- data/Licence.txt +27 -0
- data/README.txt +35 -0
- data/lib/spectrum.rb +145 -0
- data/lib/spectrum/cmyk.rb +281 -0
- data/lib/spectrum/css.rb +28 -0
- data/lib/spectrum/grayscale.rb +212 -0
- data/lib/spectrum/hsl.rb +221 -0
- data/lib/spectrum/palette.rb +16 -0
- data/lib/spectrum/palette/adobecolor.rb +272 -0
- data/lib/spectrum/palette/gimp.rb +116 -0
- data/lib/spectrum/palette/monocontrast.rb +180 -0
- data/lib/spectrum/rgb-colors.rb +355 -0
- data/lib/spectrum/rgb.rb +453 -0
- data/lib/spectrum/rgb/metallic.rb +43 -0
- data/lib/spectrum/yiq.rb +84 -0
- data/test/test_adobecolor.rb +419 -0
- data/test/test_all.rb +23 -0
- data/test/test_cmyk.rb +128 -0
- data/test/test_color.rb +141 -0
- data/test/test_css.rb +29 -0
- data/test/test_gimp.rb +101 -0
- data/test/test_grayscale.rb +121 -0
- data/test/test_hsl.rb +153 -0
- data/test/test_monocontrast.rb +142 -0
- data/test/test_rgb.rb +344 -0
- data/test/test_yiq.rb +73 -0
- metadata +108 -0
data/lib/spectrum/css.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#--
|
2
|
+
# Spectrum
|
3
|
+
# Colour management with Ruby
|
4
|
+
# http://rubyforge.org/projects/color
|
5
|
+
# Version 1.4.1
|
6
|
+
#
|
7
|
+
# Licensed under a MIT-style licence. See Licence.txt in the main
|
8
|
+
# distribution for full licensing information.
|
9
|
+
#
|
10
|
+
# Copyright (c) 2005 - 2010 Austin Ziegler and Matt Lyon
|
11
|
+
#++
|
12
|
+
|
13
|
+
require 'color'
|
14
|
+
|
15
|
+
# This namespace contains some CSS colour names.
|
16
|
+
module Spectrum::CSS
|
17
|
+
# Returns the RGB colour for name or +nil+ if the name is not valid.
|
18
|
+
def self.[](name)
|
19
|
+
@colors[name.to_s.downcase.to_sym]
|
20
|
+
end
|
21
|
+
|
22
|
+
@colors = {}
|
23
|
+
Spectrum::RGB.constants.each do |const|
|
24
|
+
next if const == "PDF_FORMAT_STR"
|
25
|
+
next if const == "Metallic"
|
26
|
+
@colors[const.downcase.to_sym] ||= Spectrum::RGB.const_get(const)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
#--
|
2
|
+
# Color
|
3
|
+
# Colour management with Ruby
|
4
|
+
# http://rubyforge.org/projects/color
|
5
|
+
# Version 1.4.1
|
6
|
+
#
|
7
|
+
# Licensed under a MIT-style licence. See Licence.txt in the main
|
8
|
+
# distribution for full licensing information.
|
9
|
+
#
|
10
|
+
# Copyright (c) 2005 - 2010 Austin Ziegler and Matt Lyon
|
11
|
+
#++
|
12
|
+
|
13
|
+
# A colour object representing shades of grey. Used primarily in PDF
|
14
|
+
# document creation.
|
15
|
+
class Spectrum::GrayScale
|
16
|
+
# The format of a DeviceGrey colour for PDF. In color-tools 2.0 this will
|
17
|
+
# be removed from this package and added back as a modification by the
|
18
|
+
# PDF::Writer package.
|
19
|
+
PDF_FORMAT_STR = "%.3f %s"
|
20
|
+
|
21
|
+
# Creates a greyscale colour object from fractional values 0..1.
|
22
|
+
#
|
23
|
+
# Spectrum::GreyScale.from_fraction(0.5)
|
24
|
+
def self.from_fraction(g = 0)
|
25
|
+
color = Spectrum::GrayScale.new
|
26
|
+
color.g = g
|
27
|
+
color
|
28
|
+
end
|
29
|
+
|
30
|
+
# Creates a greyscale colour object from percentages 0..100.
|
31
|
+
#
|
32
|
+
# Spectrum::GrayScale.from_percent(50)
|
33
|
+
def self.from_percent(g = 0)
|
34
|
+
Spectrum::GrayScale.new(g)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Creates a greyscale colour object from percentages 0..100.
|
38
|
+
#
|
39
|
+
# Spectrum::GrayScale.new(50)
|
40
|
+
def initialize(g = 0)
|
41
|
+
@g = g / 100.0
|
42
|
+
end
|
43
|
+
|
44
|
+
# Compares the other colour to this one. The other colour will be
|
45
|
+
# converted to GreyScale before comparison, so the comparison between a
|
46
|
+
# GreyScale colour and a non-GreyScale colour will be approximate and
|
47
|
+
# based on the other colour's #to_greyscale conversion. If there is no
|
48
|
+
# #to_greyscale conversion, this will raise an exception. This will report
|
49
|
+
# that two GreyScale values are equivalent if they are within
|
50
|
+
# COLOR_TOLERANCE of each other.
|
51
|
+
def ==(other)
|
52
|
+
other = other.to_grayscale
|
53
|
+
other.kind_of?(Spectrum::GrayScale) and
|
54
|
+
((@g - other.g).abs <= Spectrum::COLOR_TOLERANCE)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Present the colour as a DeviceGrey fill colour string for PDF. This will
|
58
|
+
# be removed from the default package in color-tools 2.0.
|
59
|
+
def pdf_fill
|
60
|
+
PDF_FORMAT_STR % [ @g, "g" ]
|
61
|
+
end
|
62
|
+
|
63
|
+
# Present the colour as a DeviceGrey stroke colour string for PDF. This
|
64
|
+
# will be removed from the default package in color-tools 2.0.
|
65
|
+
def pdf_stroke
|
66
|
+
PDF_FORMAT_STR % [ @g, "G" ]
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_255
|
70
|
+
[(@g * 255).round, 255].min
|
71
|
+
end
|
72
|
+
private :to_255
|
73
|
+
|
74
|
+
# Present the colour as an HTML/CSS colour string.
|
75
|
+
def html
|
76
|
+
gs = "%02x" % to_255
|
77
|
+
"##{gs * 3}"
|
78
|
+
end
|
79
|
+
|
80
|
+
# Present the colour as an RGB HTML/CSS colour string (e.g., "rgb(0%, 50%,
|
81
|
+
# 100%)").
|
82
|
+
def css_rgb
|
83
|
+
"rgb(%3.2f%%, %3.2f%%, %3.2f%%)" % [ gray, gray, gray ]
|
84
|
+
end
|
85
|
+
|
86
|
+
# Present the colour as an RGBA (with alpha) HTML/CSS colour string (e.g.,
|
87
|
+
# "rgb(0%, 50%, 100%, 1)").
|
88
|
+
def css_rgba
|
89
|
+
"rgba(%3.2f%%, %3.2f%%, %3.2f%%, %1.2f)" % [ gray, gray, gray, 1 ]
|
90
|
+
end
|
91
|
+
|
92
|
+
# Present the colour as an HSL HTML/CSS colour string (e.g., "hsl(180,
|
93
|
+
# 25%, 35%)"). Note that this will perform a #to_hsl operation.
|
94
|
+
def css_hsl
|
95
|
+
to_hsl.css_hsl
|
96
|
+
end
|
97
|
+
|
98
|
+
# Present the colour as an HSLA (with alpha) HTML/CSS colour string (e.g.,
|
99
|
+
# "hsla(180, 25%, 35%, 1)"). Note that this will perform a #to_hsl
|
100
|
+
# operation.
|
101
|
+
def css_hsla
|
102
|
+
to_hsl.css_hsla
|
103
|
+
end
|
104
|
+
|
105
|
+
# Convert the greyscale colour to CMYK.
|
106
|
+
def to_cmyk
|
107
|
+
k = 1.0 - @g.to_f
|
108
|
+
Spectrum::CMYK.from_fraction(0, 0, 0, k)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Convert the greyscale colour to RGB.
|
112
|
+
def to_rgb(ignored = true)
|
113
|
+
Spectrum::RGB.from_fraction(g, g, g)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Reflexive conversion.
|
117
|
+
def to_grayscale
|
118
|
+
self
|
119
|
+
end
|
120
|
+
alias to_greyscale to_grayscale
|
121
|
+
|
122
|
+
# Lightens the greyscale colour by the stated percent.
|
123
|
+
def lighten_by(percent)
|
124
|
+
g = [@g + (@g * (percent / 100.0)), 1.0].min
|
125
|
+
Spectrum::GrayScale.from_fraction(g)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Darken the greyscale colour by the stated percent.
|
129
|
+
def darken_by(percent)
|
130
|
+
g = [@g - (@g * (percent / 100.0)), 0.0].max
|
131
|
+
Spectrum::GrayScale.from_fraction(g)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Returns the YIQ (NTSC) colour encoding of the greyscale value. This is
|
135
|
+
# an approximation, as the values for I and Q are calculated by treating
|
136
|
+
# the greyscale value as an RGB value. The Y (intensity or brightness)
|
137
|
+
# value is the same as the greyscale value.
|
138
|
+
def to_yiq
|
139
|
+
y = @g
|
140
|
+
i = (@g * 0.596) + (@g * -0.275) + (@g * -0.321)
|
141
|
+
q = (@g * 0.212) + (@g * -0.523) + (@g * 0.311)
|
142
|
+
Spectrum::YIQ.from_fraction(y, i, q)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns the HSL colour encoding of the greyscale value.
|
146
|
+
def to_hsl
|
147
|
+
Spectrum::HSL.from_fraction(0, 0, @g)
|
148
|
+
end
|
149
|
+
|
150
|
+
# Returns the brightness value for this greyscale value; this is the
|
151
|
+
# greyscale value itself.
|
152
|
+
def brightness
|
153
|
+
@g
|
154
|
+
end
|
155
|
+
|
156
|
+
# Returns the grayscale value as a percentage of white (100% gray is
|
157
|
+
# white).
|
158
|
+
def gray
|
159
|
+
@g * 100.0
|
160
|
+
end
|
161
|
+
alias grey gray
|
162
|
+
# Returns the grayscale value as a fractional value of white in the range
|
163
|
+
# 0.0 .. 1.0.
|
164
|
+
def g
|
165
|
+
@g
|
166
|
+
end
|
167
|
+
# Sets the grayscale value as a percentage of white.
|
168
|
+
def gray=(gg)
|
169
|
+
@g = Spectrum.normalize(gg / 100.0)
|
170
|
+
end
|
171
|
+
alias grey= gray= ;
|
172
|
+
# Returns the grayscale value as a fractional value of white in the range
|
173
|
+
# 0.0 .. 1.0.
|
174
|
+
def g=(gg)
|
175
|
+
@g = Spectrum.normalize(gg)
|
176
|
+
end
|
177
|
+
|
178
|
+
# Adds another colour to the current colour. The other colour will be
|
179
|
+
# converted to grayscale before addition. This conversion depends upon a
|
180
|
+
# #to_grayscale method on the other colour.
|
181
|
+
#
|
182
|
+
# The addition is done using the grayscale accessor methods to ensure a
|
183
|
+
# valid colour in the result.
|
184
|
+
def +(other)
|
185
|
+
other = other.to_grayscale
|
186
|
+
ng = self.dup
|
187
|
+
ng.g += other.g
|
188
|
+
ng
|
189
|
+
end
|
190
|
+
|
191
|
+
# Subtracts another colour to the current colour. The other colour will be
|
192
|
+
# converted to grayscale before subtraction. This conversion depends upon
|
193
|
+
# a #to_grayscale method on the other colour.
|
194
|
+
#
|
195
|
+
# The subtraction is done using the grayscale accessor methods to ensure a
|
196
|
+
# valid colour in the result.
|
197
|
+
def -(other)
|
198
|
+
other = other.to_grayscale
|
199
|
+
ng = self.dup
|
200
|
+
ng.g -= other.g
|
201
|
+
ng
|
202
|
+
end
|
203
|
+
|
204
|
+
def inspect
|
205
|
+
"Gray [%.2f%%]" % [ gray ]
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
module Spectrum
|
210
|
+
# A synonym for Spectrum::GrayScale.
|
211
|
+
GreyScale = GrayScale
|
212
|
+
end
|
data/lib/spectrum/hsl.rb
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
#--
|
2
|
+
# Color
|
3
|
+
# Colour management with Ruby
|
4
|
+
# http://rubyforge.org/projects/color
|
5
|
+
# Version 1.4.1
|
6
|
+
#
|
7
|
+
# Licensed under a MIT-style licence. See Licence.txt in the main
|
8
|
+
# distribution for full licensing information.
|
9
|
+
#
|
10
|
+
# Copyright (c) 2005 - 2010 Austin Ziegler and Matt Lyon
|
11
|
+
#++
|
12
|
+
|
13
|
+
# An HSL colour object. Internally, the hue (#h), saturation (#s), and
|
14
|
+
# luminosity/lightness (#l) values are dealt with as fractional values in
|
15
|
+
# the range 0..1.
|
16
|
+
class Spectrum::HSL
|
17
|
+
class << self
|
18
|
+
# Creates an HSL colour object from fractional values 0..1.
|
19
|
+
def from_fraction(h = 0.0, s = 0.0, l = 0.0)
|
20
|
+
colour = Spectrum::HSL.new
|
21
|
+
colour.h = h
|
22
|
+
colour.s = s
|
23
|
+
colour.l = l
|
24
|
+
colour
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Compares the other colour to this one. The other colour will be
|
29
|
+
# converted to HSL before comparison, so the comparison between a HSL
|
30
|
+
# colour and a non-HSL colour will be approximate and based on the other
|
31
|
+
# colour's #to_hsl conversion. If there is no #to_hsl conversion, this
|
32
|
+
# will raise an exception. This will report that two HSL values are
|
33
|
+
# equivalent if all component values are within Spectrum::COLOR_TOLERANCE of
|
34
|
+
# each other.
|
35
|
+
def ==(other)
|
36
|
+
other = other.to_hsl
|
37
|
+
other.kind_of?(Spectrum::HSL) and
|
38
|
+
((@h - other.h).abs <= Spectrum::COLOR_TOLERANCE) and
|
39
|
+
((@s - other.s).abs <= Spectrum::COLOR_TOLERANCE) and
|
40
|
+
((@l - other.l).abs <= Spectrum::COLOR_TOLERANCE)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Creates an HSL colour object from the standard values of degrees and
|
44
|
+
# percentages (e.g., 145 deg, 30%, 50%).
|
45
|
+
def initialize(h = 0, s = 0, l = 0)
|
46
|
+
@h = h / 360.0
|
47
|
+
@s = s / 100.0
|
48
|
+
@l = l / 100.0
|
49
|
+
end
|
50
|
+
|
51
|
+
# Present the colour as an HTML/CSS colour string.
|
52
|
+
def html
|
53
|
+
to_rgb.html
|
54
|
+
end
|
55
|
+
|
56
|
+
# Present the colour as an RGB HTML/CSS colour string (e.g., "rgb(0%, 50%,
|
57
|
+
# 100%)"). Note that this will perform a #to_rgb operation using the
|
58
|
+
# default conversion formula.
|
59
|
+
def css_rgb
|
60
|
+
to_rgb.css_rgb
|
61
|
+
end
|
62
|
+
|
63
|
+
# Present the colour as an RGBA (with alpha) HTML/CSS colour string (e.g.,
|
64
|
+
# "rgb(0%, 50%, 100%, 1)"). Note that this will perform a #to_rgb
|
65
|
+
# operation using the default conversion formula.
|
66
|
+
def css_rgba
|
67
|
+
to_rgb.css_rgba
|
68
|
+
end
|
69
|
+
|
70
|
+
# Present the colour as an HSL HTML/CSS colour string (e.g., "hsl(180,
|
71
|
+
# 25%, 35%)").
|
72
|
+
def css_hsl
|
73
|
+
"hsl(%3.2f, %3.2f%%, %3.2f%%)" % [ hue, saturation, luminosity ]
|
74
|
+
end
|
75
|
+
|
76
|
+
# Present the colour as an HSLA (with alpha) HTML/CSS colour string (e.g.,
|
77
|
+
# "hsla(180, 25%, 35%, 1)").
|
78
|
+
def css_hsla
|
79
|
+
"hsla(%3.2f, %3.2f%%, %3.2f%%, %3.2f)" % [ hue, saturation, luminosity, 1 ]
|
80
|
+
end
|
81
|
+
|
82
|
+
# Converting to HSL as adapted from Foley and Van-Dam from
|
83
|
+
# http://www.bobpowell.net/RGBHSB.htm.
|
84
|
+
#
|
85
|
+
# NOTE:
|
86
|
+
# * If the colour's luminosity is near zero, the colour is always black.
|
87
|
+
# * If the colour's luminosity is near one, the colour is always white.
|
88
|
+
# * If the colour's saturation is near zero, the colour is always a shade
|
89
|
+
# of grey and is based only on the luminosity of the colour.
|
90
|
+
#
|
91
|
+
def to_rgb(ignored = nil)
|
92
|
+
return Spectrum::RGB.new if Color.near_zero_or_less?(@l)
|
93
|
+
return Spectrum::RGB.new(0xff, 0xff, 0xff) if Color.near_one_or_more?(@l)
|
94
|
+
return Spectrum::RGB.from_fraction(@l, @l, @l) if Color.near_zero?(@s)
|
95
|
+
|
96
|
+
# Is the value less than 0.5?
|
97
|
+
if Color.near_zero_or_less?(@l - 0.5)
|
98
|
+
tmp2 = @l * (1.0 + @s.to_f)
|
99
|
+
else
|
100
|
+
tmp2 = @l + @s - (@l * @s.to_f)
|
101
|
+
end
|
102
|
+
tmp1 = 2.0 * @l - tmp2
|
103
|
+
|
104
|
+
tmp3 = [ @h + (1.0 / 3.0), @h, @h - (1.0 / 3.0) ]
|
105
|
+
|
106
|
+
rgb = tmp3.map { |hue|
|
107
|
+
hue += 1.0 if Color.near_zero_or_less?(hue)
|
108
|
+
hue -= 1.0 if Color.near_one_or_more?(hue)
|
109
|
+
|
110
|
+
if Color.near_zero_or_less?((6.0 * hue) - 1.0)
|
111
|
+
tmp1 + ((tmp2 - tmp1) * hue * 6.0)
|
112
|
+
elsif Color.near_zero_or_less?((2.0 * hue) - 1.0)
|
113
|
+
tmp2
|
114
|
+
elsif Color.near_zero_or_less?((3.0 * hue) - 2.0)
|
115
|
+
tmp1 + (tmp2 - tmp1) * ((2 / 3.0) - hue) * 6.0
|
116
|
+
else
|
117
|
+
tmp1
|
118
|
+
end
|
119
|
+
}
|
120
|
+
|
121
|
+
Spectrum::RGB.from_fraction(*rgb)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Converts to RGB then YIQ.
|
125
|
+
def to_yiq
|
126
|
+
to_rgb.to_yiq
|
127
|
+
end
|
128
|
+
|
129
|
+
# Converts to RGB then CMYK.
|
130
|
+
def to_cmyk
|
131
|
+
to_rgb.to_cmyk
|
132
|
+
end
|
133
|
+
|
134
|
+
# Returns the luminosity (#l) of the colour.
|
135
|
+
def brightness
|
136
|
+
@l
|
137
|
+
end
|
138
|
+
def to_greyscale
|
139
|
+
Spectrum::GrayScale.from_fraction(@l)
|
140
|
+
end
|
141
|
+
alias to_grayscale to_greyscale
|
142
|
+
|
143
|
+
# Returns the hue of the colour in degrees.
|
144
|
+
def hue
|
145
|
+
@h * 360.0
|
146
|
+
end
|
147
|
+
# Returns the hue of the colour in the range 0.0 .. 1.0.
|
148
|
+
def h
|
149
|
+
@h
|
150
|
+
end
|
151
|
+
# Sets the hue of the colour in degrees. Colour is perceived as a wheel,
|
152
|
+
# so values should be set properly even with negative degree values.
|
153
|
+
def hue=(hh)
|
154
|
+
hh = hh / 360.0
|
155
|
+
|
156
|
+
hh += 1.0 if hh < 0.0
|
157
|
+
hh -= 1.0 if hh > 1.0
|
158
|
+
|
159
|
+
@h = Color.normalize(hh)
|
160
|
+
end
|
161
|
+
# Sets the hue of the colour in the range 0.0 .. 1.0.
|
162
|
+
def h=(hh)
|
163
|
+
@h = Color.normalize(hh)
|
164
|
+
end
|
165
|
+
# Returns the percentage of saturation of the colour.
|
166
|
+
def saturation
|
167
|
+
@s * 100.0
|
168
|
+
end
|
169
|
+
# Returns the saturation of the colour in the range 0.0 .. 1.0.
|
170
|
+
def s
|
171
|
+
@s
|
172
|
+
end
|
173
|
+
# Sets the percentage of saturation of the colour.
|
174
|
+
def saturation=(ss)
|
175
|
+
@s = Color.normalize(ss / 100.0)
|
176
|
+
end
|
177
|
+
# Sets the saturation of the colour in the ragne 0.0 .. 1.0.
|
178
|
+
def s=(ss)
|
179
|
+
@s = Color.normalize(ss)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns the percentage of luminosity of the colour.
|
183
|
+
def luminosity
|
184
|
+
@l * 100.0
|
185
|
+
end
|
186
|
+
alias lightness luminosity
|
187
|
+
# Returns the luminosity of the colour in the range 0.0 .. 1.0.
|
188
|
+
def l
|
189
|
+
@l
|
190
|
+
end
|
191
|
+
# Sets the percentage of luminosity of the colour.
|
192
|
+
def luminosity=(ll)
|
193
|
+
@l = Color.normalize(ll / 100.0)
|
194
|
+
end
|
195
|
+
alias lightness= luminosity= ;
|
196
|
+
# Sets the luminosity of the colour in the ragne 0.0 .. 1.0.
|
197
|
+
def l=(ll)
|
198
|
+
@l = Color.normalize(ll)
|
199
|
+
end
|
200
|
+
|
201
|
+
def to_hsl
|
202
|
+
self
|
203
|
+
end
|
204
|
+
|
205
|
+
def inspect
|
206
|
+
"HSL [%.2f deg, %.2f%%, %.2f%%]" % [ hue, saturation, luminosity ]
|
207
|
+
end
|
208
|
+
|
209
|
+
# Mix the mask colour (which will be converted to an HSL colour) with the
|
210
|
+
# current colour at the stated mix percentage as a decimal value.
|
211
|
+
#
|
212
|
+
# NOTE:: This differs from Spectrum::RGB#mix_with.
|
213
|
+
def mix_with(color, mix_percent = 0.5)
|
214
|
+
color = color.to_hsl
|
215
|
+
_h = ((color.h - self.h) * mix_percent) + self.h
|
216
|
+
_s = ((color.s - self.s) * mix_percent) + self.s
|
217
|
+
_l = ((color.l - self.l) * mix_percent) + self.l
|
218
|
+
|
219
|
+
self.class.from_fraction(_h, _s, _l)
|
220
|
+
end
|
221
|
+
end
|