color 1.5.1 → 1.6
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.
- checksums.yaml +8 -8
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.autotest +5 -0
- data/.minitest.rb +2 -0
- data/.travis.yml +35 -0
- data/Contributing.rdoc +3 -0
- data/Gemfile +9 -0
- data/History.rdoc +18 -0
- data/Licence.rdoc +1 -1
- data/Manifest.txt +9 -1
- data/README.rdoc +13 -21
- data/Rakefile +33 -17
- data/lib/color.rb +1 -1
- data/lib/color/rgb.rb +280 -97
- data/lib/color/rgb/contrast.rb +57 -0
- data/test/minitest_helper.rb +6 -0
- data/test/test_rgb.rb +41 -0
- metadata +41 -55
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NzUzZTAyZmI4OGRlNmJlZWJiZDdhZDk5NmFhNDFiNGU4ZjNmMTQxNA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YzJhMDQ1ZjdkYjgzNWM3YzFhNWYzYzAwMTkwOTViZjUzZDhhOGRmMQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NmQxOWEyNjJiZTJiNWQ1YzUxNGQzMzQ3MDhiYmI4MGRlN2Y1ZDg1OGIyNGY2
|
10
|
+
NGRmYzA1YTI5YmExZTYzNTAzMDFkOTIxNTYyYTliZGJlN2IwYzU2OWZiYjMz
|
11
|
+
YWMyNWViNWE5M2RiZGFmYzk1NDk2MzExZDk0NmI4YzVjNTg3NGM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ODkwMWY4NWNjMTRlMWJiOWY0ZjM0NzE0NjY2MDIwNWU0N2E5NjQxMmM1YTJi
|
14
|
+
MDFiZjYzMzY0MzBhOTZhYjk5MTVkOGRiYmIwNTdjNDQ3MWU2NmE5MTZkMjhh
|
15
|
+
MWYzMDk5YzY3NzA1OGQzZjg0OGNiYWRmZWJiOTNkOWI0YmM0NzM=
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.autotest
ADDED
data/.minitest.rb
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
---
|
2
|
+
language: ruby
|
3
|
+
rvm:
|
4
|
+
- 2.1.0
|
5
|
+
- 2.0.0
|
6
|
+
- 1.9.3
|
7
|
+
- jruby-19mode
|
8
|
+
- rbx-2
|
9
|
+
- 1.8.7
|
10
|
+
- jruby-18mode
|
11
|
+
- ree
|
12
|
+
- ruby-head
|
13
|
+
- jruby-head
|
14
|
+
matrix:
|
15
|
+
allow_failures:
|
16
|
+
- rvm: rbx-2
|
17
|
+
gemfile:
|
18
|
+
- Gemfile
|
19
|
+
before_script:
|
20
|
+
- |
|
21
|
+
case "${TRAVIS_RUBY_VERSION}" in
|
22
|
+
rbx*)
|
23
|
+
gem install psych
|
24
|
+
;;
|
25
|
+
esac
|
26
|
+
- rake travis:before -t
|
27
|
+
script: rake travis
|
28
|
+
after_script:
|
29
|
+
- rake travis:after -t
|
30
|
+
notifications:
|
31
|
+
email:
|
32
|
+
recipients:
|
33
|
+
- austin@rubyforge.org
|
34
|
+
on_success: change
|
35
|
+
on_failure: always
|
data/Contributing.rdoc
CHANGED
data/Gemfile
ADDED
data/History.rdoc
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
== 1.6 / 2014-05-19
|
2
|
+
|
3
|
+
* Major enhancements:
|
4
|
+
* Aaron Hill (@armahillo) implemented the CIE Delta E 94 method by which an
|
5
|
+
RGB colour can be asked for the closest matching colour from a list of
|
6
|
+
provided colours. Fixes #5.
|
7
|
+
* To implement #closest_match and #delta_e94, conversion methods for sRGB to
|
8
|
+
XYZ and XYZ to L*a*b* space were implemented. These should be considered
|
9
|
+
experimental.
|
10
|
+
|
11
|
+
* Tooling fixes:
|
12
|
+
* Ensured that the gem manifest was up-to-date. Fixes #4 reported by @boutil.
|
13
|
+
Thanks!
|
14
|
+
* Fixed problems with Travis builds. Note that Ruby 1.9.2 is no longer
|
15
|
+
tested. Rubinius remains in a “failure-tolerated” mode.
|
16
|
+
* Color 1.6 is, barring security patches, the last release of Color that will
|
17
|
+
support Ruby 1.8.
|
18
|
+
|
1
19
|
== 1.5.1 / 2014-01-28
|
2
20
|
|
3
21
|
* color 1.5 was a yanked release.
|
data/Licence.rdoc
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
This software is available under an MIT-style licence.
|
4
4
|
|
5
|
-
* Copyright 2005–
|
5
|
+
* Copyright 2005–2014 Austin Ziegler, Matt Lyon, and other contributors
|
6
6
|
|
7
7
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
8
8
|
this software and associated documentation files (the "Software"), to deal in
|
data/Manifest.txt
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
+
.autotest
|
2
|
+
.gemtest
|
1
3
|
.hoerc
|
4
|
+
.minitest.rb
|
5
|
+
.travis.yml
|
6
|
+
Contributing.rdoc
|
7
|
+
Gemfile
|
2
8
|
History.rdoc
|
3
9
|
Licence.rdoc
|
4
10
|
Manifest.txt
|
@@ -13,10 +19,12 @@ lib/color/palette.rb
|
|
13
19
|
lib/color/palette/adobecolor.rb
|
14
20
|
lib/color/palette/gimp.rb
|
15
21
|
lib/color/palette/monocontrast.rb
|
16
|
-
lib/color/rgb/colors.rb
|
17
22
|
lib/color/rgb.rb
|
23
|
+
lib/color/rgb/colors.rb
|
24
|
+
lib/color/rgb/contrast.rb
|
18
25
|
lib/color/rgb/metallic.rb
|
19
26
|
lib/color/yiq.rb
|
27
|
+
test/minitest_helper.rb
|
20
28
|
test/test_adobecolor.rb
|
21
29
|
test/test_cmyk.rb
|
22
30
|
test/test_color.rb
|
data/README.rdoc
CHANGED
@@ -4,8 +4,8 @@ home :: http://color.rubyforge.org
|
|
4
4
|
code :: https://github.com/halostatue/color
|
5
5
|
bugs :: https://github.com/halostatue/color/issues
|
6
6
|
rdoc :: http://rubydoc.info/github/halostatue/color
|
7
|
-
code climate :: {<img src="https://codeclimate.com/github/halostatue/color.png" />}[https://codeclimate.com/github/halostatue/color]
|
8
7
|
continuous integration :: {<img src="https://travis-ci.org/halostatue/color.png" />}[https://travis-ci.org/halostatue/color]
|
8
|
+
test coverage :: {<img src="https://coveralls.io/repos/halostatue/color/badge.png" alt="Coverage Status" />}[https://coveralls.io/r/halostatue/color]
|
9
9
|
|
10
10
|
== Description
|
11
11
|
|
@@ -15,28 +15,20 @@ named RGB colours (184 with spelling variations) that are commonly supported in
|
|
15
15
|
HTML, SVG, and X11 applications. A technique for generating monochromatic
|
16
16
|
contrasting palettes is also included.
|
17
17
|
|
18
|
-
The
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
L*a*b*, XYZ) to non-absolute colour spaces (like RGB).
|
18
|
+
The Color library performs purely mathematical manipulation of the colours
|
19
|
+
based on colour theory without reference to colour profiles (such as sRGB or
|
20
|
+
Adobe RGB). For most purposes, when working with RGB and HSL colour spaces,
|
21
|
+
this won't matter. Absolute colour spaces (like CIE L*a*b* and XYZ) and cannot
|
22
|
+
be reliably converted to relative colour spaces (like RGB) without colour
|
23
|
+
profiles.
|
25
24
|
|
26
|
-
Color version 1.
|
27
|
-
|
28
|
-
|
29
|
-
lib/color/rgb/contrast.rb) provided by Dave Heitzman, and methods suggested by
|
30
|
-
Thomas Sawyer based on the Spectrum library.
|
25
|
+
Color version 1.6 primarily adds a colour matching method for RGB and
|
26
|
+
experimental CIE L*a*b* and XYZ conversion methods for use with the colour
|
27
|
+
matching method.
|
31
28
|
|
32
|
-
Barring bugs introduced in this release, this
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
=== Note about color 1.5
|
37
|
-
|
38
|
-
Color 1.5 was released before the documetation was complete and has been
|
39
|
-
yanked.
|
29
|
+
Barring bugs introduced in this release, this is the last version of color that
|
30
|
+
supports Ruby 1.8, so make sure that your gem specification is set properly (to
|
31
|
+
<tt>~> 1.6</tt>) if that matters for your application.
|
40
32
|
|
41
33
|
== History
|
42
34
|
|
data/Rakefile
CHANGED
@@ -8,24 +8,20 @@ Hoe.plugin :email
|
|
8
8
|
Hoe.plugin :gemspec2
|
9
9
|
Hoe.plugin :git
|
10
10
|
Hoe.plugin :minitest
|
11
|
-
Hoe.plugin :rubyforge
|
12
11
|
Hoe.plugin :travis
|
12
|
+
Hoe.plugin :email unless ENV['CI'] or ENV['TRAVIS']
|
13
13
|
|
14
14
|
spec = Hoe.spec 'color' do
|
15
|
-
developer('Austin Ziegler', '
|
15
|
+
developer('Austin Ziegler', 'halostatue@gmail.com')
|
16
16
|
developer('Matt Lyon', 'matt@postsomnia.com')
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
# self.require_ruby_version '>= 1.9.2'
|
18
|
+
license 'MIT'
|
21
19
|
|
22
|
-
self.
|
23
|
-
self.rsync_args << ' --exclude=statsvn/'
|
20
|
+
self.need_tar = true
|
24
21
|
|
25
22
|
self.history_file = 'History.rdoc'
|
26
23
|
self.readme_file = 'README.rdoc'
|
27
24
|
self.extra_rdoc_files = FileList["*.rdoc"].to_a
|
28
|
-
self.licenses = ["MIT"]
|
29
25
|
|
30
26
|
self.extra_dev_deps << ['hoe-doofus', '~> 1.0']
|
31
27
|
self.extra_dev_deps << ['hoe-gemspec2', '~> 1.1']
|
@@ -34,16 +30,36 @@ spec = Hoe.spec 'color' do
|
|
34
30
|
self.extra_dev_deps << ['hoe-travis', '~> 1.2']
|
35
31
|
self.extra_dev_deps << ['minitest', '~> 5.0']
|
36
32
|
self.extra_dev_deps << ['rake', '~> 10.0']
|
33
|
+
|
34
|
+
if RUBY_VERSION >= '1.9' and (ENV['CI'] or ENV['TRAVIS'])
|
35
|
+
self.extra_dev_deps << ['simplecov', '~> 0.7']
|
36
|
+
self.extra_dev_deps << ['coveralls', '~> 0.7']
|
37
|
+
end
|
37
38
|
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
40
|
+
if RUBY_VERSION >= '1.9'
|
41
|
+
namespace :test do
|
42
|
+
desc "Submit test coverage to Coveralls"
|
43
|
+
task :coveralls do
|
44
|
+
spec.test_prelude = [
|
45
|
+
'require "psych"',
|
46
|
+
'require "simplecov"',
|
47
|
+
'require "coveralls"',
|
48
|
+
'SimpleCov.formatter = Coveralls::SimpleCov::Formatter',
|
49
|
+
].join('; ')
|
50
|
+
Rake::Task['test'].execute
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "Runs test coverage. Only works Ruby 1.9+ and assumes 'simplecov' is installed."
|
54
|
+
task :coverage do
|
55
|
+
spec.test_prelude = [
|
56
|
+
'require "simplecov"',
|
57
|
+
'SimpleCov.start("test_frameworks") { command_name "Minitest" }',
|
58
|
+
'gem "minitest"'
|
59
|
+
].join('; ')
|
60
|
+
Rake::Task['test'].execute
|
61
|
+
end
|
48
62
|
end
|
63
|
+
|
64
|
+
Rake::Task['travis'].prerequisites.replace(%w(test:coveralls))
|
49
65
|
end
|
data/lib/color.rb
CHANGED
data/lib/color/rgb.rb
CHANGED
@@ -7,102 +7,6 @@ class Color::RGB
|
|
7
7
|
# PDF::Writer package.
|
8
8
|
PDF_FORMAT_STR = "%.3f %.3f %.3f %s"
|
9
9
|
|
10
|
-
class << self
|
11
|
-
# Creates an RGB colour object from percentages 0..100.
|
12
|
-
#
|
13
|
-
# Color::RGB.from_percentage(10, 20 30)
|
14
|
-
def from_percentage(r = 0, g = 0, b = 0, &block)
|
15
|
-
new(r, g, b, 100.0, &block)
|
16
|
-
end
|
17
|
-
|
18
|
-
# Creates an RGB colour object from fractional values 0..1.
|
19
|
-
#
|
20
|
-
# Color::RGB.from_fraction(.3, .2, .1)
|
21
|
-
def from_fraction(r = 0.0, g = 0.0, b = 0.0, &block)
|
22
|
-
new(r, g, b, 1.0, &block)
|
23
|
-
end
|
24
|
-
|
25
|
-
# Creates an RGB colour object from a grayscale fractional value 0..1.
|
26
|
-
def from_grayscale_fraction(l = 0.0, &block)
|
27
|
-
new(l, l, l, 1.0, &block)
|
28
|
-
end
|
29
|
-
alias_method :from_greyscale_fraction, :from_grayscale_fraction
|
30
|
-
|
31
|
-
# Creates an RGB colour object from an HTML colour descriptor (e.g.,
|
32
|
-
# <tt>"fed"</tt> or <tt>"#cabbed;"</tt>.
|
33
|
-
#
|
34
|
-
# Color::RGB.from_html("fed")
|
35
|
-
# Color::RGB.from_html("#fed")
|
36
|
-
# Color::RGB.from_html("#cabbed")
|
37
|
-
# Color::RGB.from_html("cabbed")
|
38
|
-
def from_html(html_colour, &block)
|
39
|
-
# When we can move to 1.9+ only, this will be \h
|
40
|
-
h = html_colour.scan(/[0-9a-f]/i)
|
41
|
-
case h.size
|
42
|
-
when 3
|
43
|
-
new(*h.map { |v| (v * 2).to_i(16) }, &block)
|
44
|
-
when 6
|
45
|
-
new(*h.each_slice(2).map { |v| v.join.to_i(16) }, &block)
|
46
|
-
else
|
47
|
-
raise ArgumentError, "Not a supported HTML colour type."
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# Find or create a colour by an HTML hex code. This differs from the
|
52
|
-
# #from_html method in that if the colour code matches a named colour,
|
53
|
-
# the existing colour will be returned.
|
54
|
-
#
|
55
|
-
# Color::RGB.by_hex('ff0000').name # => 'red'
|
56
|
-
# Color::RGB.by_hex('ff0001').name # => nil
|
57
|
-
#
|
58
|
-
# If a block is provided, the value that is returned by the block will
|
59
|
-
# be returned instead of the exception caused by an error in providing a
|
60
|
-
# correct hex format.
|
61
|
-
def by_hex(hex, &block)
|
62
|
-
__by_hex.fetch(html_hexify(hex)) { from_html(hex) }
|
63
|
-
rescue
|
64
|
-
if block
|
65
|
-
block.call
|
66
|
-
else
|
67
|
-
raise
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Return a colour as identified by the colour name.
|
72
|
-
def by_name(name, &block)
|
73
|
-
__by_name.fetch(name.to_s.downcase, &block)
|
74
|
-
end
|
75
|
-
|
76
|
-
# Return a colour as identified by the colour name, or by hex.
|
77
|
-
def by_css(name_or_hex, &block)
|
78
|
-
by_name(name_or_hex) { by_hex(name_or_hex, &block) }
|
79
|
-
end
|
80
|
-
|
81
|
-
# Extract named or hex colours from the provided text.
|
82
|
-
def extract_colors(text, mode = :both)
|
83
|
-
text = text.downcase
|
84
|
-
regex = case mode
|
85
|
-
when :name
|
86
|
-
Regexp.union(__by_name.keys)
|
87
|
-
when :hex
|
88
|
-
Regexp.union(__by_hex.keys)
|
89
|
-
when :both
|
90
|
-
Regexp.union(__by_hex.keys + __by_name.keys)
|
91
|
-
end
|
92
|
-
|
93
|
-
text.scan(regex).map { |match|
|
94
|
-
case mode
|
95
|
-
when :name
|
96
|
-
by_name(match)
|
97
|
-
when :hex
|
98
|
-
by_hex(match)
|
99
|
-
when :both
|
100
|
-
by_css(match)
|
101
|
-
end
|
102
|
-
}
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
10
|
# Coerces the other Color object into RGB.
|
107
11
|
def coerce(other)
|
108
12
|
other.to_rgb
|
@@ -269,6 +173,78 @@ class Color::RGB
|
|
269
173
|
Color::HSL.from_fraction(hue, sat, lum)
|
270
174
|
end
|
271
175
|
|
176
|
+
# Returns the XYZ colour encoding of the value. Based on the
|
177
|
+
# {RGB to XYZ}[http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html]
|
178
|
+
# formula presented by Bruce Lindbloom.
|
179
|
+
#
|
180
|
+
# Currently only the sRGB colour space is supported.
|
181
|
+
def to_xyz(color_space = :sRGB)
|
182
|
+
unless color_space.to_s.downcase == 'srgb'
|
183
|
+
raise ArgumentError, "Unsupported colour space #{color_space}."
|
184
|
+
end
|
185
|
+
|
186
|
+
# Inverse sRGB companding. Linearizes RGB channels with respect to
|
187
|
+
# energy.
|
188
|
+
r, g, b = [ @r, @g, @b ].map { |v|
|
189
|
+
if (v > 0.04045)
|
190
|
+
(((v + 0.055) / 1.055) ** 2.4) * 100
|
191
|
+
else
|
192
|
+
(v / 12.92) * 100
|
193
|
+
end
|
194
|
+
}
|
195
|
+
|
196
|
+
# Convert using the RGB/XYZ matrix at:
|
197
|
+
# http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html#WSMatrices
|
198
|
+
{
|
199
|
+
:x => (r * 0.4124564 + g * 0.3575761 + b * 0.1804375),
|
200
|
+
:y => (r * 0.2126729 + g * 0.7151522 + b * 0.0721750),
|
201
|
+
:z => (r * 0.0193339 + g * 0.1191920 + b * 0.9503041)
|
202
|
+
}
|
203
|
+
end
|
204
|
+
|
205
|
+
# Returns the L*a*b* colour encoding of the value via the XYZ colour
|
206
|
+
# encoding. Based on the
|
207
|
+
# {XYZ to Lab}[http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html]
|
208
|
+
# formula presented by Bruce Lindbloom.
|
209
|
+
#
|
210
|
+
# Currently only the sRGB colour space is supported and defaults to using
|
211
|
+
# a D65 reference white.
|
212
|
+
def to_lab(color_space = :sRGB, reference_white = [ 95.047, 100.00, 108.883 ])
|
213
|
+
xyz = to_xyz
|
214
|
+
|
215
|
+
# Calculate the ratio of the XYZ values to the reference white.
|
216
|
+
# http://www.brucelindbloom.com/index.html?Equations.html
|
217
|
+
xr = xyz[:x] / reference_white[0]
|
218
|
+
yr = xyz[:y] / reference_white[1]
|
219
|
+
zr = xyz[:z] / reference_white[2]
|
220
|
+
|
221
|
+
# NOTE: This should be using Rational instead of floating point values,
|
222
|
+
# otherwise there will be discontinuities.
|
223
|
+
# http://www.brucelindbloom.com/LContinuity.html
|
224
|
+
epsilon = (216 / 24389.0)
|
225
|
+
kappa = (24389 / 27.0)
|
226
|
+
|
227
|
+
# And now transform
|
228
|
+
# http://en.wikipedia.org/wiki/Lab_color_space#Forward_transformation
|
229
|
+
# There is a brief explanation there as far as the nature of the calculations,
|
230
|
+
# as well as a much nicer looking modeling of the algebra.
|
231
|
+
fx, fy, fz = [ xr, yr, zr ].map { |t|
|
232
|
+
if (t > (epsilon))
|
233
|
+
t ** (1.0 / 3)
|
234
|
+
else # t <= epsilon
|
235
|
+
((kappa * t) + 16) / 116.0
|
236
|
+
# The 4/29 here is for when t = 0 (black). 4/29 * 116 = 16, and 16 -
|
237
|
+
# 16 = 0, which is the correct value for L* with black.
|
238
|
+
# ((1.0/3)*((29.0/6)**2) * t) + (4.0/29)
|
239
|
+
end
|
240
|
+
}
|
241
|
+
{
|
242
|
+
:L => ((116 * fy) - 16),
|
243
|
+
:a => (500 * (fx - fy)),
|
244
|
+
:b => (200 * (fy - fz))
|
245
|
+
}
|
246
|
+
end
|
247
|
+
|
272
248
|
# Mix the RGB hue with White so that the RGB hue is the specified
|
273
249
|
# percentage of the resulting colour. Strictly speaking, this isn't a
|
274
250
|
# darken_by operation.
|
@@ -350,6 +326,117 @@ class Color::RGB
|
|
350
326
|
hsl.to_rgb
|
351
327
|
end
|
352
328
|
|
329
|
+
# TODO: Identify the base colour profile used for L*a*b* and XYZ
|
330
|
+
# conversions.
|
331
|
+
|
332
|
+
# Calculates and returns the closest match to this colour from a list of
|
333
|
+
# provided colours. Returns +nil+ if +color_list+ is empty or if there is
|
334
|
+
# no colour within the +threshold_distance+.
|
335
|
+
#
|
336
|
+
# +threshold_distance+ is used to determine the minimum colour distance
|
337
|
+
# permitted. Uses the CIE Delta E 1994 algorithm (CIE94) to find near
|
338
|
+
# matches based on perceived visual colour. The default value (1000.0) is
|
339
|
+
# an arbitrarily large number. The values <tt>:jnd</tt> and
|
340
|
+
# <tt>:just_noticeable</tt> may be passed as the +threshold_distance+ to
|
341
|
+
# use the value <tt>2.3</tt>.
|
342
|
+
def closest_match(color_list, threshold_distance = 1000.0)
|
343
|
+
color_list = [ color_list ].flatten(1)
|
344
|
+
return nil if color_list.empty?
|
345
|
+
|
346
|
+
threshold_distance = case threshold_distance
|
347
|
+
when :jnd, :just_noticeable
|
348
|
+
2.3
|
349
|
+
else
|
350
|
+
threshold_distance.to_f
|
351
|
+
end
|
352
|
+
lab = to_lab
|
353
|
+
closest_distance = threshold_distance
|
354
|
+
best_match = nil
|
355
|
+
|
356
|
+
color_list.each do |c|
|
357
|
+
distance = delta_e94(lab, c.to_lab)
|
358
|
+
if (distance < closest_distance)
|
359
|
+
closest_distance = distance
|
360
|
+
best_match = c
|
361
|
+
end
|
362
|
+
end
|
363
|
+
best_match
|
364
|
+
end
|
365
|
+
|
366
|
+
# The Delta E (CIE94) algorithm
|
367
|
+
# http://en.wikipedia.org/wiki/Color_difference#CIE94
|
368
|
+
#
|
369
|
+
# There is a newer version, CIEDE2000, that uses slightly more complicated
|
370
|
+
# math, but addresses "the perceptual uniformity issue" left lingering by
|
371
|
+
# the CIE94 algorithm. color_1 and color_2 are both L*a*b* hashes,
|
372
|
+
# rendered by #to_lab.
|
373
|
+
#
|
374
|
+
# Since our source is treated as sRGB, we use the "graphic arts" presets
|
375
|
+
# for k_L, k_1, and k_2
|
376
|
+
#
|
377
|
+
# The calculations go through LCH(ab). (?)
|
378
|
+
#
|
379
|
+
# See also http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE94.html
|
380
|
+
#
|
381
|
+
# NOTE: This should be moved to Color::Lab.
|
382
|
+
def delta_e94(color_1, color_2, weighting_type = :graphic_arts)
|
383
|
+
case weighting_type
|
384
|
+
when :graphic_arts
|
385
|
+
k_1 = 0.045
|
386
|
+
k_2 = 0.015
|
387
|
+
k_L = 1
|
388
|
+
when :textiles
|
389
|
+
k_1 = 0.048
|
390
|
+
k_2 = 0.014
|
391
|
+
k_L = 2
|
392
|
+
else
|
393
|
+
raise ArgumentError, "Unsupported weighting type #{weighting_type}."
|
394
|
+
end
|
395
|
+
|
396
|
+
# delta_E = Math.sqrt(
|
397
|
+
# ((delta_L / (k_L * s_L)) ** 2) +
|
398
|
+
# ((delta_C / (k_C * s_C)) ** 2) +
|
399
|
+
# ((delta_H / (k_H * s_H)) ** 2)
|
400
|
+
# )
|
401
|
+
#
|
402
|
+
# Under some circumstances in real computers, delta_H could be an
|
403
|
+
# imaginary number (it's a square root value), so we're going to treat
|
404
|
+
# this as:
|
405
|
+
#
|
406
|
+
# delta_E = Math.sqrt(
|
407
|
+
# ((delta_L / (k_L * s_L)) ** 2) +
|
408
|
+
# ((delta_C / (k_C * s_C)) ** 2) +
|
409
|
+
# (delta_H2 / ((k_H * s_H) ** 2)))
|
410
|
+
# )
|
411
|
+
#
|
412
|
+
# And not perform the square root when calculating delta_H2.
|
413
|
+
|
414
|
+
k_C = k_H = 1
|
415
|
+
|
416
|
+
l_1, a_1, b_1 = color_1.values_at(:L, :a, :b)
|
417
|
+
l_2, a_2, b_2 = color_2.values_at(:L, :a, :b)
|
418
|
+
|
419
|
+
delta_a = a_1 - a_2
|
420
|
+
delta_b = b_1 - b_2
|
421
|
+
|
422
|
+
c_1 = Math.sqrt((a_1 ** 2) + (b_1 ** 2))
|
423
|
+
c_2 = Math.sqrt((a_2 ** 2) + (b_2 ** 2))
|
424
|
+
|
425
|
+
delta_L = color_1[:L] - color_2[:L]
|
426
|
+
delta_C = c_1 - c_2
|
427
|
+
|
428
|
+
delta_H2 = (delta_a ** 2) + (delta_b ** 2) - (delta_C ** 2)
|
429
|
+
|
430
|
+
s_L = 1
|
431
|
+
s_C = 1 + k_1 * c_1
|
432
|
+
s_H = 1 + k_2 * c_1
|
433
|
+
|
434
|
+
composite_L = (delta_L / (k_L * s_L)) ** 2
|
435
|
+
composite_C = (delta_C / (k_C * s_C)) ** 2
|
436
|
+
composite_H = delta_H2 / ((k_H * s_H) ** 2)
|
437
|
+
Math.sqrt(composite_L + composite_C + composite_H)
|
438
|
+
end
|
439
|
+
|
353
440
|
# Returns the red component of the colour in the normal 0 .. 255 range.
|
354
441
|
def red
|
355
442
|
@r * 255.0
|
@@ -454,7 +541,7 @@ class Color::RGB
|
|
454
541
|
# Retrieve the maxmum RGB value from the current colour as a GrayScale
|
455
542
|
# colour
|
456
543
|
def max_rgb_as_grayscale
|
457
|
-
|
544
|
+
Color::GrayScale.from_fraction([@r, @g, @b].max)
|
458
545
|
end
|
459
546
|
alias max_rgb_as_greyscale max_rgb_as_grayscale
|
460
547
|
|
@@ -486,6 +573,102 @@ class Color::RGB
|
|
486
573
|
end
|
487
574
|
end
|
488
575
|
|
576
|
+
class << Color::RGB
|
577
|
+
# Creates an RGB colour object from percentages 0..100.
|
578
|
+
#
|
579
|
+
# Color::RGB.from_percentage(10, 20, 30)
|
580
|
+
def from_percentage(r = 0, g = 0, b = 0, &block)
|
581
|
+
new(r, g, b, 100.0, &block)
|
582
|
+
end
|
583
|
+
|
584
|
+
# Creates an RGB colour object from fractional values 0..1.
|
585
|
+
#
|
586
|
+
# Color::RGB.from_fraction(.3, .2, .1)
|
587
|
+
def from_fraction(r = 0.0, g = 0.0, b = 0.0, &block)
|
588
|
+
new(r, g, b, 1.0, &block)
|
589
|
+
end
|
590
|
+
|
591
|
+
# Creates an RGB colour object from a grayscale fractional value 0..1.
|
592
|
+
def from_grayscale_fraction(l = 0.0, &block)
|
593
|
+
new(l, l, l, 1.0, &block)
|
594
|
+
end
|
595
|
+
alias_method :from_greyscale_fraction, :from_grayscale_fraction
|
596
|
+
|
597
|
+
# Creates an RGB colour object from an HTML colour descriptor (e.g.,
|
598
|
+
# <tt>"fed"</tt> or <tt>"#cabbed;"</tt>.
|
599
|
+
#
|
600
|
+
# Color::RGB.from_html("fed")
|
601
|
+
# Color::RGB.from_html("#fed")
|
602
|
+
# Color::RGB.from_html("#cabbed")
|
603
|
+
# Color::RGB.from_html("cabbed")
|
604
|
+
def from_html(html_colour, &block)
|
605
|
+
# When we can move to 1.9+ only, this will be \h
|
606
|
+
h = html_colour.scan(/[0-9a-f]/i)
|
607
|
+
case h.size
|
608
|
+
when 3
|
609
|
+
new(*h.map { |v| (v * 2).to_i(16) }, &block)
|
610
|
+
when 6
|
611
|
+
new(*h.each_slice(2).map { |v| v.join.to_i(16) }, &block)
|
612
|
+
else
|
613
|
+
raise ArgumentError, "Not a supported HTML colour type."
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
# Find or create a colour by an HTML hex code. This differs from the
|
618
|
+
# #from_html method in that if the colour code matches a named colour,
|
619
|
+
# the existing colour will be returned.
|
620
|
+
#
|
621
|
+
# Color::RGB.by_hex('ff0000').name # => 'red'
|
622
|
+
# Color::RGB.by_hex('ff0001').name # => nil
|
623
|
+
#
|
624
|
+
# If a block is provided, the value that is returned by the block will
|
625
|
+
# be returned instead of the exception caused by an error in providing a
|
626
|
+
# correct hex format.
|
627
|
+
def by_hex(hex, &block)
|
628
|
+
__by_hex.fetch(html_hexify(hex)) { from_html(hex) }
|
629
|
+
rescue
|
630
|
+
if block
|
631
|
+
block.call
|
632
|
+
else
|
633
|
+
raise
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
637
|
+
# Return a colour as identified by the colour name.
|
638
|
+
def by_name(name, &block)
|
639
|
+
__by_name.fetch(name.to_s.downcase, &block)
|
640
|
+
end
|
641
|
+
|
642
|
+
# Return a colour as identified by the colour name, or by hex.
|
643
|
+
def by_css(name_or_hex, &block)
|
644
|
+
by_name(name_or_hex) { by_hex(name_or_hex, &block) }
|
645
|
+
end
|
646
|
+
|
647
|
+
# Extract named or hex colours from the provided text.
|
648
|
+
def extract_colors(text, mode = :both)
|
649
|
+
text = text.downcase
|
650
|
+
regex = case mode
|
651
|
+
when :name
|
652
|
+
Regexp.union(__by_name.keys)
|
653
|
+
when :hex
|
654
|
+
Regexp.union(__by_hex.keys)
|
655
|
+
when :both
|
656
|
+
Regexp.union(__by_hex.keys + __by_name.keys)
|
657
|
+
end
|
658
|
+
|
659
|
+
text.scan(regex).map { |match|
|
660
|
+
case mode
|
661
|
+
when :name
|
662
|
+
by_name(match)
|
663
|
+
when :hex
|
664
|
+
by_hex(match)
|
665
|
+
when :both
|
666
|
+
by_css(match)
|
667
|
+
end
|
668
|
+
}
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
489
672
|
class << Color::RGB
|
490
673
|
private
|
491
674
|
def __named_color(mod, rgb, *names)
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# -*- ruby encoding: utf-8 -*-
|
2
|
+
|
3
|
+
class Color::RGB
|
4
|
+
# Outputs how much contrast this color has with another RGB color.
|
5
|
+
# Computes the same regardless of which one is considered foreground. If
|
6
|
+
# the other color does not have a #to_rgb method, this will throw an
|
7
|
+
# exception. Anything over about 0.22 should have a high likelihood of
|
8
|
+
# being legible, but the larger the difference, the more contrast.
|
9
|
+
# Otherwise, to be safe go with something > 0.3
|
10
|
+
def contrast(other)
|
11
|
+
other = coerce(other)
|
12
|
+
|
13
|
+
# The following numbers have been set with some care.
|
14
|
+
((diff_brightness(other) * 0.65) +
|
15
|
+
(diff_hue(other) * 0.20) +
|
16
|
+
(diff_luminosity(other) * 0.15))
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
# Provides the luminosity difference between two rbg vals
|
21
|
+
def diff_luminosity(other)
|
22
|
+
other = coerce(other)
|
23
|
+
l1 = (0.2126 * (other.r) ** 2.2) +
|
24
|
+
(0.7152 * (other.b) ** 2.2) +
|
25
|
+
(0.0722 * (other.g) ** 2.2);
|
26
|
+
|
27
|
+
l2 = (0.2126 * (self.r) ** 2.2) +
|
28
|
+
(0.7152 * (self.b) ** 2.2) +
|
29
|
+
(0.0722 * (self.g) ** 2.2);
|
30
|
+
|
31
|
+
((([l1, l2].max) + 0.05) / ( ([l1, l2].min) + 0.05 ) - 1) / 20.0
|
32
|
+
end
|
33
|
+
|
34
|
+
# Provides the brightness difference.
|
35
|
+
def diff_brightness(other)
|
36
|
+
other = other.to_rgb
|
37
|
+
br1 = (299 * other.r + 587 * other.g + 114 * other.b)
|
38
|
+
br2 = (299 * self.r + 587 * self.g + 114 * self.b)
|
39
|
+
(br1 - br2).abs / 1000.0;
|
40
|
+
end
|
41
|
+
|
42
|
+
# Provides the euclidean distance between the two color values
|
43
|
+
def diff_euclidean(other)
|
44
|
+
other = other.to_rgb
|
45
|
+
((((other.r - self.r) ** 2) +
|
46
|
+
((other.g - self.g) ** 2) +
|
47
|
+
((other.b - self.b) ** 2)) ** 0.5) / 1.7320508075688772
|
48
|
+
end
|
49
|
+
|
50
|
+
# Difference in the two colors' hue
|
51
|
+
def diff_hue(other)
|
52
|
+
other = other.to_rgb
|
53
|
+
((self.r - other.r).abs +
|
54
|
+
(self.g - other.g).abs +
|
55
|
+
(self.b - other.b).abs) / 3
|
56
|
+
end
|
57
|
+
end
|
data/test/test_rgb.rb
CHANGED
@@ -277,6 +277,47 @@ module TestColor
|
|
277
277
|
Color::RGB::Cayenne.to_yiq)
|
278
278
|
end
|
279
279
|
|
280
|
+
def test_to_lab
|
281
|
+
# Luminosity can be an absolute.
|
282
|
+
assert_in_delta(0.0, Color::RGB::Black.to_lab[:L], Color::COLOR_TOLERANCE)
|
283
|
+
assert_in_delta(100.0, Color::RGB::White.to_lab[:L], Color::COLOR_TOLERANCE)
|
284
|
+
|
285
|
+
# It's not really possible to have absolute
|
286
|
+
# numbers here because of how L*a*b* works, but
|
287
|
+
# negative/positive comparisons work
|
288
|
+
assert(Color::RGB::Green.to_lab[:a] < 0)
|
289
|
+
assert(Color::RGB::Magenta.to_lab[:a] > 0)
|
290
|
+
assert(Color::RGB::Blue.to_lab[:b] < 0)
|
291
|
+
assert(Color::RGB::Yellow.to_lab[:b] > 0)
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_closest_match
|
295
|
+
# It should match Blue to Indigo (very simple match)
|
296
|
+
match_from = [Color::RGB::Red, Color::RGB::Green, Color::RGB::Blue]
|
297
|
+
assert_equal(Color::RGB::Blue, Color::RGB::Indigo.closest_match(match_from))
|
298
|
+
# But fails if using the :just_noticeable difference.
|
299
|
+
assert_nil(Color::RGB::Indigo.closest_match(match_from, :just_noticeable))
|
300
|
+
|
301
|
+
# Crimson & Firebrick are visually closer than DarkRed and Firebrick
|
302
|
+
# (more precise match)
|
303
|
+
match_from += [Color::RGB::DarkRed, Color::RGB::Crimson]
|
304
|
+
assert_equal(Color::RGB::Crimson,
|
305
|
+
Color::RGB::Firebrick.closest_match(match_from))
|
306
|
+
# Specifying a threshold low enough will cause even that match to
|
307
|
+
# fail, though.
|
308
|
+
assert_nil(Color::RGB::Firebrick.closest_match(match_from, 8.0))
|
309
|
+
# If the match_from list is an empty array, it also returns nil
|
310
|
+
assert_nil(Color::RGB::Red.closest_match([]))
|
311
|
+
|
312
|
+
# RGB::Green is 0,128,0, so we'll pick something VERY close to it, visually
|
313
|
+
jnd_green = Color::RGB.new(3, 132, 3)
|
314
|
+
assert_equal(Color::RGB::Green,
|
315
|
+
jnd_green.closest_match(match_from, :jnd))
|
316
|
+
# And then something that's just barely out of the tolerance range
|
317
|
+
diff_green = Color::RGB.new(9, 142, 9)
|
318
|
+
assert_nil(diff_green.closest_match(match_from, :jnd))
|
319
|
+
end
|
320
|
+
|
280
321
|
def test_add
|
281
322
|
white = Color::RGB::Cyan + Color::RGB::Yellow
|
282
323
|
refute_nil(white)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: color
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: '1.6'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Austin Ziegler
|
@@ -11,10 +11,10 @@ bindir: bin
|
|
11
11
|
cert_chain:
|
12
12
|
- !binary |-
|
13
13
|
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUROakNDQWg2Z0F3SUJB
|
14
|
-
|
14
|
+
Z0lCQVRBTkJna3Foa2lHOXcwQkFRVUZBREJCTVE4d0RRWURWUVFEREFaaGRY
|
15
15
|
TjAKYVc0eEdUQVhCZ29Ka2lhSmsvSXNaQUVaRmdseWRXSjVabTl5WjJVeEV6
|
16
|
-
|
17
|
-
|
16
|
+
QVJCZ29Ka2lhSmsvSXNaQUVaRmdOdgpjbWN3SGhjTk1UUXdNakl5TURNME1U
|
17
|
+
UXpXaGNOTVRVd01qSXlNRE0wTVRReldqQkJNUTh3RFFZRFZRUUREQVpoCmRY
|
18
18
|
TjBhVzR4R1RBWEJnb0praWFKay9Jc1pBRVpGZ2x5ZFdKNVptOXlaMlV4RXpB
|
19
19
|
UkJnb0praWFKay9Jc1pBRVoKRmdOdmNtY3dnZ0VpTUEwR0NTcUdTSWIzRFFF
|
20
20
|
QkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDMm1QTmY0TDM3R2hLSQpTUENZc3ZZ
|
@@ -25,19 +25,19 @@ cert_chain:
|
|
25
25
|
Z3kxR1Z3VAppNnBrRHM4TGhaV1hkT0QrOTIxbDJaMU5aR1phOUtOYkpJZzZ2
|
26
26
|
dGdZS1U5OGpRNXFyOWlZM2lrQkFzcEhyRmFzCks2VVN2R2dBZzhmQ0Q1WWlv
|
27
27
|
dEJFdkNCTVl0ZnFtZnJocGRVMnArZ3ZUZ2VMVzFLYWV2d3FkN25nUW1GVXJG
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
28
|
+
RzEKZVVKU1VSdjVBZ01CQUFHak9UQTNNQWtHQTFVZEV3UUNNQUF3Q3dZRFZS
|
29
|
+
MFBCQVFEQWdTd01CMEdBMVVkRGdRVwpCQlFMU1NqS2VtR0RhcFlFZC9VNG1T
|
30
|
+
MXFyeTJvRWpBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQU5tMmFnVGRECjlT
|
31
|
+
Mk53WE1XMGphbnNJblh0UW1CNDRxay9wc1d1anRHbm4rb1QrYTlLWE81cC9n
|
32
|
+
eDJtbXg4aE1GMDJ3VUJ4MUgKazk2SFVJL2pSM0hkaFlDZkc2b0p1RXpnWHJG
|
33
|
+
aVNCSncvY09KaU04djNhSHNBd0kzTmVMZUlyUndCWUIza0kzagoxcWZKWGNP
|
34
|
+
V3c3YzYzVHJzRFgzN3hqMmU0UDBETkoxY1RyRG15RDJ5VFE1Nzc2TTEzR2I2
|
35
|
+
blhqcmVTZXEwdC9uCjYwTmo5MUoxb0hZazZMRmEwZW8vZ3lrVGJMeWFacnNh
|
36
|
+
WGxOYjNqN0NqaFV6T3BZT2hpQ1VIM3M5dEtUR1hkLysKTG1aN0J4VE1zRGha
|
37
|
+
SHkzay9FVEZoaSs3cElVV2xGbzBpbXJkeUxoZCtKdzNib1ZqM0NtdnloY3dt
|
38
|
+
cG9NMEs5bApBT21yVWlFbFVxTE9aQT09Ci0tLS0tRU5EIENFUlRJRklDQVRF
|
39
39
|
LS0tLS0K
|
40
|
-
date: 2014-
|
40
|
+
date: 2014-05-20 00:00:00.000000000 Z
|
41
41
|
dependencies:
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: minitest
|
@@ -45,28 +45,14 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - ~>
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '5.
|
48
|
+
version: '5.3'
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - ~>
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: '5.
|
56
|
-
- !ruby/object:Gem::Dependency
|
57
|
-
name: rubyforge
|
58
|
-
requirement: !ruby/object:Gem::Requirement
|
59
|
-
requirements:
|
60
|
-
- - ! '>='
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: 2.0.4
|
63
|
-
type: :development
|
64
|
-
prerelease: false
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - ! '>='
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: 2.0.4
|
55
|
+
version: '5.3'
|
70
56
|
- !ruby/object:Gem::Dependency
|
71
57
|
name: rdoc
|
72
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -171,14 +157,14 @@ dependencies:
|
|
171
157
|
requirements:
|
172
158
|
- - ~>
|
173
159
|
- !ruby/object:Gem::Version
|
174
|
-
version: '3.
|
160
|
+
version: '3.12'
|
175
161
|
type: :development
|
176
162
|
prerelease: false
|
177
163
|
version_requirements: !ruby/object:Gem::Requirement
|
178
164
|
requirements:
|
179
165
|
- - ~>
|
180
166
|
- !ruby/object:Gem::Version
|
181
|
-
version: '3.
|
167
|
+
version: '3.12'
|
182
168
|
description: ! 'Color is a Ruby library to provide basic RGB, CMYK, HSL, and other
|
183
169
|
colourspace
|
184
170
|
|
@@ -191,52 +177,50 @@ description: ! 'Color is a Ruby library to provide basic RGB, CMYK, HSL, and oth
|
|
191
177
|
contrasting palettes is also included.
|
192
178
|
|
193
179
|
|
194
|
-
The
|
195
|
-
|
196
|
-
manipulation of the colours based on colour theory without reference to colour
|
197
|
-
|
198
|
-
profiles (such as sRGB or Adobe RGB). For most purposes, when working with the
|
180
|
+
The Color library performs purely mathematical manipulation of the colours
|
199
181
|
|
200
|
-
|
182
|
+
based on colour theory without reference to colour profiles (such as sRGB or
|
201
183
|
|
202
|
-
|
184
|
+
Adobe RGB). For most purposes, when working with RGB and HSL colour spaces,
|
203
185
|
|
204
|
-
|
186
|
+
this won''t matter. Absolute colour spaces (like CIE L*a*b* and XYZ) and cannot
|
205
187
|
|
206
|
-
|
188
|
+
be reliably converted to relative colour spaces (like RGB) without colour
|
207
189
|
|
190
|
+
profiles.
|
208
191
|
|
209
|
-
Color version 1.5.1 is mostly a maintenance release, fixing some bugs that may
|
210
192
|
|
211
|
-
|
193
|
+
Color version 1.6 primarily adds a colour matching method for RGB and
|
212
194
|
|
213
|
-
|
195
|
+
experimental CIE L*a*b* and XYZ conversion methods for use with the colour
|
214
196
|
|
215
|
-
|
197
|
+
matching method.
|
216
198
|
|
217
|
-
Thomas Sawyer based on the Spectrum library.
|
218
199
|
|
200
|
+
Barring bugs introduced in this release, this is the last version of color that
|
219
201
|
|
220
|
-
|
202
|
+
supports Ruby 1.8, so make sure that your gem specification is set properly (to
|
221
203
|
|
222
|
-
|
223
|
-
|
224
|
-
properly, to <tt>~> 1.5</tt> if that matters for your application.'
|
204
|
+
<tt>~> 1.6</tt>) if that matters for your application.'
|
225
205
|
email:
|
226
|
-
-
|
206
|
+
- halostatue@gmail.com
|
227
207
|
- matt@postsomnia.com
|
228
208
|
executables: []
|
229
209
|
extensions: []
|
230
210
|
extra_rdoc_files:
|
211
|
+
- Contributing.rdoc
|
231
212
|
- History.rdoc
|
232
213
|
- Licence.rdoc
|
233
214
|
- Manifest.txt
|
234
215
|
- README.rdoc
|
235
|
-
- Contributing.rdoc
|
236
216
|
files:
|
217
|
+
- .autotest
|
237
218
|
- .gemtest
|
238
219
|
- .hoerc
|
220
|
+
- .minitest.rb
|
221
|
+
- .travis.yml
|
239
222
|
- Contributing.rdoc
|
223
|
+
- Gemfile
|
240
224
|
- History.rdoc
|
241
225
|
- Licence.rdoc
|
242
226
|
- Manifest.txt
|
@@ -253,8 +237,10 @@ files:
|
|
253
237
|
- lib/color/palette/monocontrast.rb
|
254
238
|
- lib/color/rgb.rb
|
255
239
|
- lib/color/rgb/colors.rb
|
240
|
+
- lib/color/rgb/contrast.rb
|
256
241
|
- lib/color/rgb/metallic.rb
|
257
242
|
- lib/color/yiq.rb
|
243
|
+
- test/minitest_helper.rb
|
258
244
|
- test/test_adobecolor.rb
|
259
245
|
- test/test_cmyk.rb
|
260
246
|
- test/test_color.rb
|
@@ -286,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
286
272
|
- !ruby/object:Gem::Version
|
287
273
|
version: '0'
|
288
274
|
requirements: []
|
289
|
-
rubyforge_project:
|
275
|
+
rubyforge_project:
|
290
276
|
rubygems_version: 2.2.1
|
291
277
|
signing_key:
|
292
278
|
specification_version: 4
|
metadata.gz.sig
CHANGED
Binary file
|