color_lib 1.4.4

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.
@@ -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
@@ -0,0 +1,4 @@
1
+ require 'color_lib'
2
+
3
+ module ColorLib::Palette
4
+ end