be9-colorist 0.0.3

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,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
@@ -0,0 +1,10 @@
1
+ = 0.0.3 - 2009-06-19 (by be9)
2
+
3
+ * Allow Colorist::Color subclassing
4
+ * Fix rounding in Colorist::Color.from_rgb(:percent=>true)
5
+ * Add Colorist::Color#adjust method
6
+ * Colorist::Color#invert is aliased as #opposite
7
+
8
+ = 0.0.2 - 2007-09-17
9
+
10
+ * Colorist::Color.from_string and String#to_color now work with capitalized colors as well as lowercase.
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2008 Michael Bleigh and Intridea, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,27 @@
1
+ = Colorist
2
+
3
+ Colorist is a library built to handle the conversion, comparison, and
4
+ manipulation of colors in Ruby projects with an emphasis on W3C standards
5
+ and CSS-style hex notation. See the Color class for additional details
6
+ on the available methods.
7
+
8
+ == Example
9
+
10
+ require 'colorist'
11
+ include Colorist
12
+
13
+ gray = Color.new(0x333333)
14
+ gray + gray # => #<Color #666666>
15
+ gray - "#333" # => #<Color #000000>
16
+
17
+ gray.invert # => #<Color #cccccc>
18
+ gray.brightness # => 0.2
19
+
20
+ gray.contrast_with("#f00")
21
+
22
+ == Resources
23
+
24
+ * GitHub Source: http://github.com/mbleigh/colorist
25
+ * Lighthouse (for bugs): http://mbleigh.lighthouseapp.com/projects/15686-colorist
26
+
27
+ Copyright (c) 2008 Michael Bleigh and Intridea, Inc. Released under the MIT open source license.
@@ -0,0 +1,61 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "colorist"
8
+ gem.summary = %Q{A library built to handle the easy conversion and simple manipulation of colors.}
9
+ gem.email = "michael@intridea.com"
10
+ gem.homepage = "http://github.com/be9/colorist"
11
+ gem.authors = ["Michael Bleigh", "oleg dashevskii"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ gem.description = "Colorist is a library built to handle the easy conversion and manipulation of colors with a special emphasis on W3C standards and CSS-style hex color notation."
14
+ gem.has_rdoc = true
15
+ gem.rdoc_options = ["--main", "README.rdoc"]
16
+ gem.extra_rdoc_files = ["MIT_LICENSE.rdoc", "README.rdoc"]
17
+ end
18
+
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
21
+ end
22
+
23
+ =begin
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/*_test.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ begin
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/*_test.rb'
36
+ test.verbose = true
37
+ end
38
+ rescue LoadError
39
+ task :rcov do
40
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
+ end
42
+ end
43
+
44
+
45
+ task :default => :test
46
+ =end
47
+
48
+ require 'rake/rdoctask'
49
+ Rake::RDocTask.new do |rdoc|
50
+ if File.exist?('VERSION.yml')
51
+ config = YAML.load(File.read('VERSION.yml'))
52
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
53
+ else
54
+ version = ""
55
+ end
56
+
57
+ rdoc.rdoc_dir = 'rdoc'
58
+ rdoc.title = "colorist #{version}"
59
+ rdoc.rdoc_files.include('README*')
60
+ rdoc.rdoc_files.include('lib/**/*.rb')
61
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.3
@@ -0,0 +1,43 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{colorist}
5
+ s.version = "0.0.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Michael Bleigh", "oleg dashevskii"]
9
+ s.date = %q{2009-06-19}
10
+ s.description = %q{Colorist is a library built to handle the easy conversion and manipulation of colors with a special emphasis on W3C standards and CSS-style hex color notation.}
11
+ s.email = %q{michael@intridea.com}
12
+ s.extra_rdoc_files = [
13
+ "MIT_LICENSE.rdoc",
14
+ "README.rdoc"
15
+ ]
16
+ s.files = [
17
+ ".gitignore",
18
+ "CHANGELOG.rdoc",
19
+ "MIT_LICENSE.rdoc",
20
+ "README.rdoc",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "colorist.gemspec",
24
+ "lib/colorist.rb",
25
+ "lib/colorist/color.rb",
26
+ "lib/colorist/core_extensions.rb"
27
+ ]
28
+ s.homepage = %q{http://github.com/be9/colorist}
29
+ s.rdoc_options = ["--main", "README.rdoc"]
30
+ s.require_paths = ["lib"]
31
+ s.rubygems_version = %q{1.3.3}
32
+ s.summary = %q{A library built to handle the easy conversion and simple manipulation of colors.}
33
+
34
+ if s.respond_to? :specification_version then
35
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
36
+ s.specification_version = 3
37
+
38
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
39
+ else
40
+ end
41
+ else
42
+ end
43
+ end
@@ -0,0 +1,2 @@
1
+ require 'colorist/color'
2
+ require 'colorist/core_extensions'
@@ -0,0 +1,331 @@
1
+ module Colorist
2
+ # Color is the general class for storing and manipulating a color with the
3
+ # Colorist gem. It provides methods to add, subtract, and calculate aspects
4
+ # of the color based on W3C and other standards.
5
+ class Color
6
+ attr_accessor :r, :g, :b
7
+
8
+ CSS_COLOR_NAMES = { "maroon" => 0x800000,
9
+ "red" => 0xff0000,
10
+ "orange" => 0xffa500,
11
+ "yellow" => 0xffff00,
12
+ "olive" => 0x808000,
13
+ "purple" => 0x800080,
14
+ "fuchsia" => 0xff00ff,
15
+ "white" => 0xffffff,
16
+ "lime" => 0x00ff00,
17
+ "green" => 0x008000,
18
+ "navy" => 0x000080,
19
+ "blue" => 0x0000ff,
20
+ "aqua" => 0x00ffff,
21
+ "teal" => 0x008080,
22
+ "black" => 0x000000,
23
+ "silver" => 0xc0c0c0,
24
+ "gray" => 0x808080 }
25
+
26
+ # Creates a new color with the hex color provided as a number (i.e. 0x112233)
27
+ def initialize(color=0x000000)
28
+ string = "%.6x" % color
29
+ @r = string[0..1].hex
30
+ @g = string[2..3].hex
31
+ @b = string[4..5].hex
32
+ end
33
+
34
+ # Initialize a color based on RGB values. By default, the values
35
+ # should be between 0 and 255. If you use the option <tt>:percent => true</tt>,
36
+ # the values should then be between 0.0 and 1.0.
37
+ def self.from_rgb(r,g,b,options={})
38
+ color = new
39
+ # convert from 0.0 to 1.0 to 0 to 255 if the :percent option is used
40
+ if options[:percent]
41
+ color.r, color.g, color.b = (r * 255).round, (g * 255).round, (b * 255).round
42
+ else
43
+ color.r, color.g, color.b = r, g, b
44
+ end
45
+ color
46
+ end
47
+
48
+ # Initialize a colour based on HSV/HSB values. Hue should be between 0 and 360 (inclusive),
49
+ # while saturation and value should be from 0.0 to 1.0.
50
+ def self.from_hsv(hue, saturation, value)
51
+ saturation = 1 if saturation > 1
52
+ value = 1 if saturation > 1
53
+
54
+ # Conversion formula taken from wikipedia
55
+
56
+ f = (hue / 60.0) - (hue / 60).floor
57
+
58
+ p = value * (1 - saturation)
59
+ q = value * (1 - (saturation * f))
60
+ t = value * (1 - (saturation * (1 - f)))
61
+
62
+ r, g, b = case (hue / 60).floor % 6
63
+ when 0 then [ value, t, p ]
64
+ when 1 then [ q, value, p ]
65
+ when 2 then [ p, value, t ]
66
+ when 3 then [ p, q, value ]
67
+ when 4 then [ t, p, value ]
68
+ when 5 then [ value, p, q ]
69
+ end
70
+
71
+ from_rgb(r, g, b, :percent => true)
72
+ end
73
+
74
+ # Converts a CSS hex string into a color. Works both with the
75
+ # full form (i.e. <tt>#ffffff</tt>) and the abbreviated form (<tt>#fff</tt>). Can
76
+ # also take any of the 16 named CSS colors.
77
+ def self.from_string(some_string)
78
+ if matched = some_string.match(/\A#([0-9a-f]{3})\z/i)
79
+ color = from_rgb(*matched[1].split(//).collect{|v| "#{v}#{v}".hex })
80
+ elsif matched = some_string.match(/\A#([0-9a-f]{6})\z/i)
81
+ color = new
82
+ color.r = matched[1][0..1].hex
83
+ color.g = matched[1][2..3].hex
84
+ color.b = matched[1][4..5].hex
85
+ elsif CSS_COLOR_NAMES.key?(some_string)
86
+ color = new(CSS_COLOR_NAMES[some_string])
87
+ else
88
+ raise ArgumentError, "Must provide a valid CSS hex color or color name.", caller
89
+ end
90
+ color
91
+ end
92
+
93
+ # Create a new color from the provided object. Duplicates Color objects
94
+ # and attempts to call <tt>to_color</tt> on other objects. Will raise
95
+ # an ArgumentError if it is unable to coerce the color.
96
+ def self.from(some_entity)
97
+ case some_entity
98
+ when Colorist::Color
99
+ some_entity.dup
100
+ else
101
+ raise ArgumentError, "#{some_entity.class.to_s} cannot be coerced into a color.", caller unless some_entity.respond_to?(:to_color)
102
+ some_entity.to_color
103
+ end
104
+ end
105
+
106
+ # Create a duplicate of this color.
107
+ def dup
108
+ self.class.from_rgb(@r,@g,@b)
109
+ end
110
+
111
+ # Add the individual RGB values of two colors together. You
112
+ # may also use an equivalent numeric or string color representation.
113
+ #
114
+ # Examples:
115
+ #
116
+ # gray = Colorist::Color.new(0x333333)
117
+ # gray + "#300" # => <Color #663333>
118
+ # gray + 0x000000 # => <Color #333333>
119
+ # white = "white".to_color
120
+ # gray + white # => <Color #ffffff>
121
+ def +(other_color)
122
+ other_color = self.class.from(other_color)
123
+ color = self.dup
124
+ color.r += other_color.r
125
+ color.g += other_color.g
126
+ color.b += other_color.b
127
+ color
128
+ end
129
+
130
+ # Subtract the individual RGB values of the two colors together.
131
+ # You may also use an equivalent numeric or string color representation.
132
+ def -(other_color)
133
+ other_color = self.class.from(other_color)
134
+ color = self.dup
135
+ color.r -= other_color.r
136
+ color.g -= other_color.g
137
+ color.b -= other_color.b
138
+ color
139
+ end
140
+
141
+ # Compares colors based on brightness.
142
+ def <=>(other_color)
143
+ other_color = self.class.from(other_color)
144
+ brightness <=> other_color.brightness
145
+ end
146
+
147
+ # Compares colors based on brightness.
148
+ def < (other_color)
149
+ other_color = self.class.from(other_color)
150
+ brightness < other_color.brightness
151
+ end
152
+
153
+ # Compares colors based on brightness.
154
+ def > (other_color)
155
+ other_color = self.class.from(other_color)
156
+ brightness > other_color.brightness
157
+ end
158
+
159
+ # Equal if the red, green, and blue values are identical.
160
+ def ==(other_color)
161
+ other_color = self.class.from(other_color)
162
+ other_color.r == self.r && other_color.g == self.g && other_color.b == self.b
163
+ end
164
+
165
+ # Equal if the brightnesses of the two colors are identical.
166
+ def ===(other_color)
167
+ other_color = self.class.from(other_color)
168
+ other_color.brightness == brightness
169
+ end
170
+
171
+ def r=(value) #:nodoc:
172
+ @r = value; normalize; end
173
+ def g=(value) #:nodoc:
174
+ @g = value; normalize; end
175
+ def b=(value) #:nodoc:
176
+ @b = value; normalize; end
177
+
178
+ # Outputs a string representation of the color in the desired format.
179
+ # The available formats are:
180
+ #
181
+ # * <tt>:css</tt> - As a CSS hex string (i.e. <tt>#ffffff</tt>) (default)
182
+ # * <tt>:css_rgb</tt> - As a CSS RGB value string (i.e. <tt>rgb(255,255,255)</tt>)
183
+ # * <tt>:rgb</tt> - As an RGB triplet (i.e. <tt>1.0, 1.0, 1.0</tt>)
184
+ def to_s(format=:css)
185
+ case format
186
+ when :css
187
+ "#%.2x%.2x%.2x" % [r, g, b]
188
+ when :css_rgb
189
+ "rgb(%.2f,%.2f,%.2f)" % [r, g, b]
190
+ when :rgb
191
+ "%.3f, %.3f, %.3f" % [r / 255, g / 255, b / 255]
192
+ end
193
+ end
194
+
195
+ # Returns an array of the hue, saturation and value of the color.
196
+ # Hue will range from 0-359, hue and saturation will be between 0 and 1.
197
+
198
+ def to_hsv
199
+ red, green, blue = *[r, g, b].collect {|x| x / 255.0}
200
+ max = [red, green, blue].max
201
+ min = [red, green, blue].min
202
+
203
+ if min == max
204
+ hue = 0
205
+ elsif max == red
206
+ hue = 60 * ((green - blue) / (max - min))
207
+ elsif max == green
208
+ hue = 60 * ((blue - red) / (max - min)) + 120
209
+ elsif max == blue
210
+ hue = 60 * ((red - green) / (max - min)) + 240
211
+ end
212
+
213
+ saturation = (max == 0) ? 0 : (max - min) / max
214
+ [hue % 360, saturation, max]
215
+ end
216
+
217
+ def inspect
218
+ "#<Color #{to_s(:css)}>"
219
+ end
220
+
221
+ # Returns the perceived brightness of the provided color on a
222
+ # scale of 0.0 to 1.0 based on the formula provided. The formulas
223
+ # available are:
224
+ #
225
+ # * <tt>:w3c</tt> - <tt>((r * 299 + g * 587 + b * 114) / 1000 / 255</tt>
226
+ # * <tt>:standard</tt> - <tt>sqrt(0.241 * r^2 + 0.691 * g^2 + 0.068 * b^2) / 255</tt>
227
+ def brightness(formula=:w3c)
228
+ case formula
229
+ when :standard
230
+ Math.sqrt(0.241 * r**2 + 0.691 * g**2 + 0.068 * b**2) / 255
231
+ when :w3c
232
+ ((r * 299 + g * 587 + b * 114) / 255000.0)
233
+ end
234
+ end
235
+
236
+ # Contrast this color with another color using the provided formula. The
237
+ # available formulas are:
238
+ #
239
+ # * <tt>:w3c</tt> - <tt>(max(r1 r2) - min(r1 r2)) + (max(g1 g2) - min(g1 g2)) + (max(b1 b2) - min(b1 b2))</tt>
240
+ def contrast_with(other_color, formula=:w3c)
241
+ other_color = self.class.from(other_color)
242
+ case formula
243
+ when :w3c
244
+ (([self.r, other_color.r].max - [self.r, other_color.r].min) +
245
+ ([self.g, other_color.g].max - [self.g, other_color.g].min) +
246
+ ([self.b, other_color.b].max - [self.b, other_color.b].min)) / 765.0
247
+ end
248
+ end
249
+
250
+ # Returns the opposite of the current color.
251
+ def invert
252
+ self.class.from_rgb(255 - r, 255 - g, 255 - b)
253
+ end
254
+
255
+ alias opposite invert
256
+
257
+ # Uses a naive formula to generate a gradient between this color and the given color.
258
+ # Returns the array of colors that make the gradient, including this color and the
259
+ # target color. By default will return 10 colors, but this can be changed by supplying
260
+ # an optional steps parameter.
261
+ def gradient_to(color, steps = 10)
262
+ color_to = self.class.from(color)
263
+ red = color_to.r - r
264
+ green = color_to.g - g
265
+ blue = color_to.b - b
266
+
267
+ result = (1..(steps - 3)).to_a.collect do |step|
268
+ percentage = step.to_f / (steps - 1)
269
+ self.class.from_rgb(r + (red * percentage), g + (green * percentage), b + (blue * percentage))
270
+ end
271
+
272
+ # Add first and last colors to result, avoiding uneccessary calculation and rounding errors
273
+
274
+ result.unshift(self.dup)
275
+ result.push(color.dup)
276
+ result
277
+ end
278
+
279
+ # Converts the current color to grayscale using the brightness
280
+ # formula provided. See #brightness for a description of the
281
+ # available formulas.
282
+ def to_grayscale(formula=:w3c)
283
+ b = brightness(formula)
284
+ self.class.from_rgb(255 * b, 255 * b, 255 * b)
285
+ end
286
+
287
+ # Returns an appropriate text color (either black or white) based on
288
+ # the brightness of this color. The +threshold+ specifies the brightness
289
+ # cutoff point.
290
+ def text_color(threshold=0.6, formula=:standard)
291
+ brightness(formula) > threshold ? self.class.new(0x000000) : self.class.new(0xffffff)
292
+ end
293
+
294
+ # Adjusts any of H, S, V values with relative values: +opts[:h]+, +opts[:s]+, +opts[:v]+
295
+ # and returns adjusted value.
296
+ def adjust(opts = {})
297
+ unless [:h, :s, :v].any? { |part| opts.include? part }
298
+ raise ArgumentError, "please specify at least one of :h, :s, or :v options"
299
+ end
300
+
301
+ h, s, v = *self.to_hsv
302
+
303
+ h = _within(0, h + opts[:h], 359) if opts[:h]
304
+ s = _within(0, s + opts[:s], 1) if opts[:s]
305
+ v = _within(0, v + opts[:v], 1) if opts[:v]
306
+
307
+ self.class.from_hsv(h, s, v)
308
+ end
309
+
310
+ protected
311
+
312
+ def normalize #:nodoc:
313
+ @r = 255 if @r > 255
314
+ @g = 255 if @g > 255
315
+ @b = 255 if @b > 255
316
+ @r = 0 if @r < 0
317
+ @g = 0 if @g < 0
318
+ @b = 0 if @b < 0
319
+ end
320
+
321
+ def _within(min, value, max)
322
+ if value < min
323
+ min
324
+ elsif value > max
325
+ max
326
+ else
327
+ value
328
+ end
329
+ end
330
+ end
331
+ end
@@ -0,0 +1,26 @@
1
+ class Integer
2
+ # Converts a hexadecimal number into a Color. Must be
3
+ # the equivalent of the full hexadecimal form (for example,
4
+ # <tt>0x123456</tt>).
5
+ def to_color
6
+ Colorist::Color.new(self)
7
+ end
8
+ end
9
+
10
+ class Float
11
+ # Converts a number from 0.0 to 1.0 to the grayscale equivalent
12
+ # of that brightness value. Especially useful for adding percentages
13
+ # to a color.
14
+ def to_color
15
+ Colorist::Color.from_rgb(self * 255, self * 255, self * 255)
16
+ end
17
+ end
18
+
19
+ class String
20
+ # Converts a CSS-style color string to a Color. Can be
21
+ # in the full form (<tt>\#112233</tt>), the abbreviated form
22
+ # (<tt>\#123</tt>) or a CSS named color (<tt>"black"</tt> or <tt>"maroon"</tt>).
23
+ def to_color
24
+ Colorist::Color.from_string(self)
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: be9-colorist
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Michael Bleigh
8
+ - oleg dashevskii
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-06-19 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: Colorist is a library built to handle the easy conversion and manipulation of colors with a special emphasis on W3C standards and CSS-style hex color notation.
18
+ email: michael@intridea.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - MIT_LICENSE.rdoc
25
+ - README.rdoc
26
+ files:
27
+ - .gitignore
28
+ - CHANGELOG.rdoc
29
+ - MIT_LICENSE.rdoc
30
+ - README.rdoc
31
+ - Rakefile
32
+ - VERSION
33
+ - colorist.gemspec
34
+ - lib/colorist.rb
35
+ - lib/colorist/color.rb
36
+ - lib/colorist/core_extensions.rb
37
+ has_rdoc: false
38
+ homepage: http://github.com/be9/colorist
39
+ post_install_message:
40
+ rdoc_options:
41
+ - --main
42
+ - README.rdoc
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ requirements: []
58
+
59
+ rubyforge_project:
60
+ rubygems_version: 1.2.0
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: A library built to handle the easy conversion and simple manipulation of colors.
64
+ test_files: []
65
+