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