color-tools 1.1.0 → 1.2.0
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/Changelog +10 -0
- data/Install +5 -2
- data/README +23 -18
- data/Rakefile +4 -1
- data/lib/color.rb +11 -2
- data/lib/color/cmyk.rb +116 -51
- data/lib/color/grayscale.rb +105 -0
- data/lib/color/rgb.rb +142 -122
- data/lib/color/yiq.rb +52 -0
- data/metaconfig +4 -0
- data/pre-setup.rb +46 -0
- data/setup.rb +1366 -0
- metadata +10 -5
data/Changelog
CHANGED
@@ -1,6 +1,16 @@
|
|
1
|
+
== color-utils 1.2.0
|
2
|
+
* Changed installer from a custom-written install.rb to setup.rb
|
3
|
+
3.3.1-modified.
|
4
|
+
* Added Color::GreyScale (or Color::GrayScale).
|
5
|
+
* Added Color::YIQ. This colour definition is incomplete; it does not have
|
6
|
+
conversions from YIQ to other colour spaces.
|
7
|
+
|
1
8
|
== color-utils 1.1.0
|
2
9
|
* Added color/palette/gimp to support the reading and use of GIMP color
|
3
10
|
palettes.
|
4
11
|
|
5
12
|
== color-utils 1.0.0
|
6
13
|
* Initial release.
|
14
|
+
|
15
|
+
$Id: Changelog,v 1.4 2005/07/01 15:54:18 austin Exp $
|
16
|
+
# vim: sts=2 sw=2 ts=4 et ai tw=77
|
data/Install
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
Installing this package is as simple as:
|
2
2
|
|
3
|
-
% ruby
|
3
|
+
% ruby setup.rb
|
4
4
|
|
5
5
|
Alternatively, you can use the RubyGem version of color-tools available as
|
6
|
-
color-tools-1.
|
6
|
+
color-tools-1.2.0.gem from the usual sources.
|
7
|
+
|
8
|
+
$Id: Install,v 1.4 2005/07/01 15:54:18 austin Exp $
|
9
|
+
# vim: sts=2 sw=2 ts=4 et ai tw=77
|
data/README
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
= color-tools README
|
2
|
-
color-tools is a Ruby library to provide RGB and
|
3
|
-
applications that require it. It provides 148 named RGB colours
|
4
|
-
commonly supported and used in HTML, colour manipulation
|
5
|
-
a monochromatic contrasting palette generator.
|
6
|
-
|
7
|
-
|
2
|
+
color-tools is a Ruby library to provide RGB, CMYK, and other colour
|
3
|
+
support to applications that require it. It provides 148 named RGB colours
|
4
|
+
that are commonly supported and used in HTML, colour manipulation
|
5
|
+
operations, and a monochromatic contrasting palette generator. Version 1.2
|
6
|
+
introduces two new colour spaces: GrayScale (also known as GreyScale) and
|
7
|
+
YIQ (NTSC).
|
8
|
+
|
9
|
+
The GreyScale colour space has been added primarily to add new colour
|
10
|
+
space support for PDF::Writer (PDF documents support CMYK, RGB, and Grey
|
11
|
+
device colour spaces). The YIQ colour space has been promoted to a full
|
12
|
+
colour class to make future colour management of this class easier.
|
8
13
|
|
9
14
|
== Copyright
|
10
15
|
Copyright 2005 by Austin Ziegler
|
11
16
|
|
12
|
-
Color::RGB and Color::CMYK were originally developed for the Ruby PDF
|
13
|
-
project and PDF::Writer and represent wholly unique code.
|
14
|
-
|
15
17
|
Color::Palette was developed based on techniques described by Andy
|
16
18
|
"Malarkey" Clarke[1], implemented in JavaScript by Steve G. Chipman at
|
17
19
|
SlayerOffice[2] and by Patrick Fitzgerald of BarelyFitz[3] in PHP.
|
@@ -29,17 +31,20 @@ conditions:
|
|
29
31
|
products derived from this software without specific prior written
|
30
32
|
permission.
|
31
33
|
|
32
|
-
The above copyright notice and this permission notice shall be included
|
33
|
-
|
34
|
+
The above copyright notice and this permission notice shall be included in
|
35
|
+
all copies or substantial portions of the Software.
|
34
36
|
|
35
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
38
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
39
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
40
|
+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
41
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
42
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
43
|
+
DEALINGS IN THE SOFTWARE.
|
42
44
|
|
43
45
|
[1] http://www.stuffandnonsense.co.uk/archives/creating_colour_palettes.html
|
44
46
|
[2] http://slayeroffice.com/tools/color_palette/
|
45
47
|
[3] http://www.barelyfitz.com/projects/csscolor/
|
48
|
+
|
49
|
+
$Id: README,v 1.5 2005/07/01 15:54:18 austin Exp $
|
50
|
+
# vim: sts=2 sw=2 ts=4 et ai tw=74
|
data/Rakefile
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
#! /usr/bin/env rake
|
2
|
+
# $Id: Rakefile,v 1.5 2005/07/01 15:54:18 austin Exp $
|
3
|
+
# vim: sts=2 sw=2 ts=4 et ai tw=77
|
4
|
+
|
2
5
|
$LOAD_PATH.unshift('lib')
|
3
6
|
|
4
7
|
require 'rubygems'
|
@@ -75,7 +78,7 @@ file TARDIST => [ :test ] do |t|
|
|
75
78
|
else
|
76
79
|
mode = 0644
|
77
80
|
end
|
78
|
-
data = File.
|
81
|
+
data = File.open(dd, "rb") { |ff| ff.read }
|
79
82
|
{ :name => ddnew, :mode => mode, :data => data, :size => data.size,
|
80
83
|
:mtime => mtime }
|
81
84
|
end
|
data/lib/color.rb
CHANGED
@@ -36,12 +36,21 @@
|
|
36
36
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
37
37
|
# DEALINGS IN THE SOFTWARE.
|
38
38
|
|
39
|
+
module Color
|
40
|
+
COLOR_TOOLS_VERSION = '1.2.0'
|
41
|
+
|
42
|
+
class RGB; end
|
43
|
+
class CMYK; end
|
44
|
+
class GrayScale; end
|
45
|
+
class YIQ; end
|
46
|
+
end
|
47
|
+
|
39
48
|
require 'color/rgb'
|
40
49
|
require 'color/cmyk'
|
50
|
+
require 'color/grayscale'
|
51
|
+
require 'color/yiq'
|
41
52
|
|
42
53
|
module Color
|
43
|
-
COLOR_TOOLS_VERSION = '1.1.0'
|
44
|
-
|
45
54
|
Black = Color::RGB.new
|
46
55
|
Navy = Color::RGB.new(0x00, 0x00, 0x80)
|
47
56
|
DarkBlue = Color::RGB.new(0x00, 0x00, 0x8b)
|
data/lib/color/cmyk.rb
CHANGED
@@ -5,69 +5,134 @@
|
|
5
5
|
# http://rubyforge.org/ruby-pdf/
|
6
6
|
#++
|
7
7
|
|
8
|
-
|
8
|
+
# An CMYK colour object.
|
9
|
+
class Color::CMYK
|
10
|
+
PDF_FORMAT_STR = "%.3f %.3f %.3f %.3f %s"
|
9
11
|
|
10
|
-
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
# Compares the other colour to this one. The other colour will be
|
13
|
+
# converted to CMYK before comparison, so the comparison between a CMYK
|
14
|
+
# colour and a non-CMYK colour will be approximate and based on the
|
15
|
+
# other colour's #to_cmyk conversion. If there is no #to_cmyk
|
16
|
+
# conversion, this will raise an exception.
|
17
|
+
def ==(other)
|
18
|
+
other = other.to_cmyk
|
19
|
+
other.kind_of?(Color::CMYK) and
|
20
|
+
(@c == other.c) and
|
21
|
+
(@m == other.m) and
|
22
|
+
(@y == other.y) and
|
23
|
+
(@k == other.k)
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
# Creates a CMYK colour object from fractional values 0 .. 1.
|
27
|
+
def self.from_fraction(c = 0, m = 0, y = 0, k = 0)
|
28
|
+
colour = Color::CMYK.new
|
29
|
+
colour.c = c
|
30
|
+
colour.m = m
|
31
|
+
colour.y = y
|
32
|
+
colour.k = k
|
33
|
+
colour
|
34
|
+
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
# Creates a CMYK colour object from percentages.
|
37
|
+
def initialize(c = 0, m = 0, y = 0, k = 0)
|
38
|
+
@c = c / 100.0
|
39
|
+
@m = m / 100.0
|
40
|
+
@y = y / 100.0
|
41
|
+
@k = k / 100.0
|
42
|
+
end
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
44
|
+
# Present the colour as a DeviceCMYK fill colour string for PDF.
|
45
|
+
def pdf_fill
|
46
|
+
PDF_FORMAT_STR % [ @c, @m, @y, @k, "k" ]
|
47
|
+
end
|
46
48
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
# Present the colour as a DeviceCMYK stroke colour string for PDF.
|
50
|
+
def pdf_stroke
|
51
|
+
PDF_FORMAT_STR % [ @c, @m, @y, @k, "K" ]
|
52
|
+
end
|
51
53
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
54
|
+
# Present the colour as an RGB HTML/CSS colour string. Note that this
|
55
|
+
# will perform a #to_rgb
|
56
|
+
def html
|
57
|
+
to_rgb.html
|
58
|
+
end
|
56
59
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
60
|
+
# Converts the CMYK colour to RGB. Most colour experts strongly suggest
|
61
|
+
# that this is not a good idea (some even suggesting that it's a very
|
62
|
+
# bad idea). CMYK represents additive percentages of inks on white
|
63
|
+
# paper, whereas RGB represents mixed colour intensities on a black
|
64
|
+
# screen.
|
65
|
+
#
|
66
|
+
# However, the colour conversion can be done, and there are two
|
67
|
+
# different methods for the conversion that provide slightly different
|
68
|
+
# results. Adobe PDF conversions are done with the first form.
|
69
|
+
#
|
70
|
+
# # Adobe PDF Display Formula
|
71
|
+
# r = 1.0 - min(1.0, c + k)
|
72
|
+
# g = 1.0 - min(1.0, m + k)
|
73
|
+
# b = 1.0 - min(1.0, y + k)
|
74
|
+
#
|
75
|
+
# # Other
|
76
|
+
# r = 1.0 - (c * (1.0 - k) + k)
|
77
|
+
# g = 1.0 - (m * (1.0 - k) + k)
|
78
|
+
# b = 1.0 - (y * (1.0 - k) + k)
|
79
|
+
#
|
80
|
+
# If we have a CMYK colour of [33% 66% 83% 25%], the first method will
|
81
|
+
# give an approximate RGB colour of (107, 23, 0) or #6b1700. The second
|
82
|
+
# method will give an approximate RGB colour of (128, 65, 33) or
|
83
|
+
# #804121. Which is correct? Although the colours may seem to be
|
84
|
+
# drastically different in the RGB colour space, they are very similar
|
85
|
+
# colours, differing mostly in intensity. The first is a darker,
|
86
|
+
# slightly redder brown; the second is a lighter brown.
|
87
|
+
#
|
88
|
+
# Because of this subtlety, both methods are now offered for conversion
|
89
|
+
# in color-tools 1.2 or later. The Adobe method is not used by default;
|
90
|
+
# to enable it, pass +true+ to #to_rgb.
|
91
|
+
def to_rgb(use_adobe_method = false)
|
92
|
+
if use_adobe_method
|
93
|
+
r = 1.0 - [1.0, @c + @k].min
|
94
|
+
g = 1.0 - [1.0, @m + @k].min
|
95
|
+
b = 1.0 - [1.0, @y + @k].min
|
96
|
+
else
|
61
97
|
r = 1.0 - (@c.to_f * (1.0 - @k.to_f) + @k.to_f)
|
62
98
|
g = 1.0 - (@m.to_f * (1.0 - @k.to_f) + @k.to_f)
|
63
99
|
b = 1.0 - (@y.to_f * (1.0 - @k.to_f) + @k.to_f)
|
64
|
-
Color::RGB.from_fraction(r, g, b)
|
65
100
|
end
|
101
|
+
Color::RGB.from_fraction(r, g, b)
|
102
|
+
end
|
66
103
|
|
67
|
-
|
68
|
-
|
69
|
-
|
104
|
+
# Converts the CMYK colour to a single greyscale value. There are
|
105
|
+
# undoubtedly multiple methods for this conversion, but only a minor
|
106
|
+
# variant of the Adobe conversion method will be used:
|
107
|
+
#
|
108
|
+
# g = 1.0 - min(1.0, 0.299 * c + 0.587 * m + 0.114 * y + k)
|
109
|
+
#
|
110
|
+
# This treats the CMY values similarly to YIQ (NTSC) values and then
|
111
|
+
# adds the level of black. This is a variant of the Adobe version
|
112
|
+
# because it uses the more precise YIQ (NTSC) conversion values for Y
|
113
|
+
# (intensity) rather than the approximates provided by Adobe (0.3, 0.59,
|
114
|
+
# and 0.11).
|
115
|
+
def to_grayscale
|
116
|
+
c = 0.299 * @c.to_f
|
117
|
+
m = 0.587 * @m.to_f
|
118
|
+
y = 0.114 * @y.to_f
|
119
|
+
g = 1.0 - [1.0, c + m + y + @k].min
|
120
|
+
Color::Grayscale.from_fraction(g)
|
121
|
+
end
|
122
|
+
alias to_greyscale to_grayscale
|
123
|
+
|
124
|
+
def to_cmyk
|
125
|
+
self
|
126
|
+
end
|
70
127
|
|
71
|
-
|
128
|
+
# Returns the YIQ (NTSC) colour approximation of the CMYK value. This is
|
129
|
+
# done by first con
|
130
|
+
def to_yiq
|
131
|
+
y = (@r * 0.299) + (@g * 0.587) + (@b * 0.114)
|
132
|
+
i = (@r * 0.596) + (@g * -0.275) + (@b * -0.321)
|
133
|
+
q = (@r * 0.212) + (@g * -0.523) + (@b * 0.311)
|
134
|
+
Color::YIQ.from_fraction(y, i, q)
|
72
135
|
end
|
136
|
+
|
137
|
+
attr_accessor :c, :m, :y, :k
|
73
138
|
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
#--
|
2
|
+
# Colour management with Ruby.
|
3
|
+
#
|
4
|
+
# Copyright 2005 Austin Ziegler
|
5
|
+
# http://rubyforge.org/ruby-pdf/
|
6
|
+
#++
|
7
|
+
|
8
|
+
# A colour object representing shades of grey. Used primarily in PDF
|
9
|
+
# document creation.
|
10
|
+
class Color::GrayScale
|
11
|
+
# The format required to present the colour to a PDF document.
|
12
|
+
PDF_FORMAT_STR = "%.3f %s"
|
13
|
+
|
14
|
+
# Creates a greyscale colour object from fractional values 0 .. 1.
|
15
|
+
def self.from_fraction(g = 0)
|
16
|
+
color = Color::GrayScale.new
|
17
|
+
color.g = g
|
18
|
+
color
|
19
|
+
end
|
20
|
+
|
21
|
+
# Creates a greyscale colour object from percentages 0 .. 100.
|
22
|
+
def initialize(g = 0)
|
23
|
+
@g = g / 100.0
|
24
|
+
end
|
25
|
+
|
26
|
+
# Compares the other colour to this one. The other colour will be
|
27
|
+
# converted to GreyScale before comparison, so the comparison between a
|
28
|
+
# GreyScale colour and a non-GreyScale colour will be approximate and
|
29
|
+
# based on the other colour's #to_greyscale conversion. If there is no
|
30
|
+
# #to_greyscale conversion, this will raise an exception.
|
31
|
+
def ==(other)
|
32
|
+
other = other.to_grayscale
|
33
|
+
other.kind_of?(Color::GrayScale) and (@g == other.g)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Present the colour as a fill colour string for PDF.
|
37
|
+
def pdf_fill
|
38
|
+
PDF_FORMAT_STR % [ @g, "g" ]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Present the colour as a stroke colour string for PDF.
|
42
|
+
def pdf_stroke
|
43
|
+
PDF_FORMAT_STR % [ @g, "G" ]
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_255
|
47
|
+
[(@g * 255).round, 255].min
|
48
|
+
end
|
49
|
+
private :to_255
|
50
|
+
|
51
|
+
# Present the colour as an HTML/CSS colour string.
|
52
|
+
def html
|
53
|
+
gs = "%02x" % @g.to_255
|
54
|
+
"##{gs * 3}"
|
55
|
+
end
|
56
|
+
|
57
|
+
# Convert the greyscale colour to CMYK.
|
58
|
+
def to_cmyk
|
59
|
+
k = 1.0 - @g.to_f
|
60
|
+
Color::CMYK.from_Fraction(0, 0, 0, k)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Convert the greyscale colour to RGB.
|
64
|
+
def to_rgb(ignored = true)
|
65
|
+
g = @g.to_255
|
66
|
+
Color::RGB.new(g, g, g)
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_grayscale
|
70
|
+
self
|
71
|
+
end
|
72
|
+
alias to_greyscale to_grayscale
|
73
|
+
|
74
|
+
# Lightens the greyscale colour by the stated percent.
|
75
|
+
def lighten_by(percent)
|
76
|
+
g = [@g + (@g * (percent / 100.0)), 1.0].min
|
77
|
+
Color::Grayscale.from_fraction(g)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Darken the RGB hue by the stated percent.
|
81
|
+
def darken_by(percent)
|
82
|
+
g = [@g - (@g * (percent / 100.0)), 1.0].max
|
83
|
+
Color::GrayScale.from_fraction(g)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns the YIQ (NTSC) colour encoding of the greyscale value. This
|
87
|
+
# is an approximation, as the values for I and Q are calculated by
|
88
|
+
# treating the greyscale value as an RGB value. The Y (intensity or
|
89
|
+
# brightness) value is the same as the greyscale value.
|
90
|
+
def to_yiq
|
91
|
+
y = @g
|
92
|
+
i = (@g * 0.596) + (@g * -0.275) + (@g * -0.321)
|
93
|
+
q = (@g * 0.212) + (@g * -0.523) + (@g * 0.311)
|
94
|
+
Color::YIQ.from_fraction(y, i, q)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns the brightness value for this greyscale value; this is the
|
98
|
+
# greyscale value.
|
99
|
+
def brightness
|
100
|
+
@g
|
101
|
+
end
|
102
|
+
|
103
|
+
attr_accessor :g
|
104
|
+
end
|
105
|
+
Color::GreyScale = Color::GrayScale
|
data/lib/color/rgb.rb
CHANGED
@@ -5,151 +5,171 @@
|
|
5
5
|
# http://rubyforge.org/ruby-pdf/
|
6
6
|
#++
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
# Creates an RGB colour object from percentages 0 .. 100.
|
18
|
-
def from_percentage(r = 0, g = 0, b = 0)
|
19
|
-
from_fraction(r / 100.0, g / 100.0, b / 100.0)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Creates an RGB colour object from fractional values 0 .. 1.
|
23
|
-
def from_fraction(r = 0.0, g = 0.0, b = 0.0)
|
24
|
-
colour = Color::RGB.new
|
25
|
-
colour.instance_variable_set(:@r, r)
|
26
|
-
colour.instance_variable_set(:@g, g)
|
27
|
-
colour.instance_variable_set(:@b, b)
|
28
|
-
colour
|
29
|
-
end
|
30
|
-
|
31
|
-
# Creates an RGB colour object from an HTML colour descriptor (e.g.,
|
32
|
-
# <tt>"fed"</tt> or <tt>"#cabbed;"</tt>.
|
33
|
-
def from_html(html_colour)
|
34
|
-
html_colour = html_colour.gsub(%r{[#;]}, '')
|
35
|
-
case html_colour.size
|
36
|
-
when 3
|
37
|
-
colours = html_colour.scan(%r{[0-9A-Fa-f]}).map { |el| (el * 2).to_i(16) }
|
38
|
-
when 6
|
39
|
-
colours = html_colour.scan(%r<[0-9A-Fa-f]{2}>).map { |el| el.to_i(16) }
|
40
|
-
else
|
41
|
-
raise ArgumentError
|
42
|
-
end
|
43
|
-
|
44
|
-
Color::RGB.new(*colours)
|
45
|
-
end
|
8
|
+
# An RGB colour object.
|
9
|
+
class Color::RGB
|
10
|
+
# The format required to present the colour to a PDF document.
|
11
|
+
PDF_FORMAT_STR = "%.3f %.3f %.3f %s"
|
12
|
+
|
13
|
+
class << self
|
14
|
+
# Creates an RGB colour object from percentages 0 .. 100.
|
15
|
+
def from_percentage(r = 0, g = 0, b = 0)
|
16
|
+
from_fraction(r / 100.0, g / 100.0, b / 100.0)
|
46
17
|
end
|
47
18
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
19
|
+
# Creates an RGB colour object from fractional values 0 .. 1.
|
20
|
+
def from_fraction(r = 0.0, g = 0.0, b = 0.0)
|
21
|
+
colour = Color::RGB.new
|
22
|
+
colour.r = r
|
23
|
+
colour.g = g
|
24
|
+
colour.b = b
|
25
|
+
colour
|
54
26
|
end
|
55
27
|
|
56
|
-
# Creates an RGB colour object from
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
28
|
+
# Creates an RGB colour object from an HTML colour descriptor (e.g.,
|
29
|
+
# <tt>"fed"</tt> or <tt>"#cabbed;"</tt>.
|
30
|
+
def from_html(html_colour)
|
31
|
+
html_colour = html_colour.gsub(%r{[#;]}, '')
|
32
|
+
case html_colour.size
|
33
|
+
when 3
|
34
|
+
colours = html_colour.scan(%r{[0-9A-Fa-f]}).map { |el| (el * 2).to_i(16) }
|
35
|
+
when 6
|
36
|
+
colours = html_colour.scan(%r<[0-9A-Fa-f]{2}>).map { |el| el.to_i(16) }
|
37
|
+
else
|
38
|
+
raise ArgumentError
|
39
|
+
end
|
62
40
|
|
63
|
-
|
64
|
-
def pdf_fill
|
65
|
-
PDF_FORMAT_STR % [ @r, @g, @b, "rg" ]
|
41
|
+
Color::RGB.new(*colours)
|
66
42
|
end
|
43
|
+
end
|
67
44
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
45
|
+
def ==(other)
|
46
|
+
other = other.to_rgb
|
47
|
+
other.kind_of?(Color::RGB) and
|
48
|
+
(@r == other.r) and
|
49
|
+
(@g == other.g) and
|
50
|
+
(@b == other.b)
|
51
|
+
end
|
72
52
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
53
|
+
# Creates an RGB colour object from the standard range 0 .. 255.
|
54
|
+
def initialize(r = 0, g = 0, b = 0)
|
55
|
+
@r = r / 255.0
|
56
|
+
@g = g / 255.0
|
57
|
+
@b = b / 255.0
|
58
|
+
end
|
77
59
|
|
78
|
-
|
79
|
-
|
60
|
+
# Present the colour as a fill colour string for PDF.
|
61
|
+
def pdf_fill
|
62
|
+
PDF_FORMAT_STR % [ @r, @g, @b, "rg" ]
|
63
|
+
end
|
80
64
|
|
81
|
-
|
82
|
-
|
65
|
+
# Present the colour as a stroke colour string for PDF.
|
66
|
+
def pdf_stroke
|
67
|
+
PDF_FORMAT_STR % [ @r, @g, @b, "RG" ]
|
68
|
+
end
|
83
69
|
|
84
|
-
|
85
|
-
|
70
|
+
# Present the colour as an HTML/CSS colour string.
|
71
|
+
def html
|
72
|
+
r = (@r * 255).round
|
73
|
+
r = 255 if r > 255
|
86
74
|
|
87
|
-
|
88
|
-
|
89
|
-
# inks, not mixed colour intensities like RGB.
|
90
|
-
def to_cmyk
|
91
|
-
c = 1.0 - @r.to_f
|
92
|
-
m = 1.0 - @g.to_f
|
93
|
-
y = 1.0 - @b.to_f
|
75
|
+
g = (@g * 255).round
|
76
|
+
g = 255 if g > 255
|
94
77
|
|
95
|
-
|
96
|
-
|
97
|
-
k = m if m < k
|
98
|
-
k = y if y < k
|
78
|
+
b = (@b * 255).round
|
79
|
+
b = 255 if b > 255
|
99
80
|
|
100
|
-
|
101
|
-
|
102
|
-
y = (y.to_f - k.to_f) / (1.0 - k.to_f)
|
81
|
+
"#%02x%02x%02x" % [ r, g, b ]
|
82
|
+
end
|
103
83
|
|
104
|
-
|
105
|
-
|
84
|
+
# Converts the RGB colour to CMYK. Most colour experts strongly suggest
|
85
|
+
# that this is not a good idea (some even suggesting that it's a very
|
86
|
+
# bad idea). CMYK represents additive percentages of inks on white
|
87
|
+
# paper, whereas RGB represents mixed colour intensities on a black
|
88
|
+
# screen.
|
89
|
+
#
|
90
|
+
# However, the colour conversion can be done. The basic method is
|
91
|
+
# multi-step:
|
92
|
+
#
|
93
|
+
# 1. Convert the R, G, and B components to C, M, and Y components.
|
94
|
+
# c = 1.0 � r
|
95
|
+
# m = 1.0 � g
|
96
|
+
# y = 1.0 � b
|
97
|
+
# 2. Compute the minimum amount of black (K) required to smooth the
|
98
|
+
# colour in inks.
|
99
|
+
# k = min(c, m, y)
|
100
|
+
# 3. Perform undercolour removal on the C, M, and Y components of the
|
101
|
+
# colours because less of each colour is needed for each bit of
|
102
|
+
# black. Also, regenerate the black (K) based on the undercolour
|
103
|
+
# removal so that the colour is more accurately represented in ink.
|
104
|
+
# c = min(1.0, max(0.0, c � UCR(k)))
|
105
|
+
# m = min(1.0, max(0.0, m � UCR(k)))
|
106
|
+
# y = min(1.0, max(0.0, y � UCR(k)))
|
107
|
+
# k = min(1.0, max(0.0, BG(k)))
|
108
|
+
#
|
109
|
+
# The undercolour removal function and the black generation functions
|
110
|
+
# return a value based on the brightness of the RGB colour.
|
111
|
+
def to_cmyk
|
112
|
+
c = 1.0 - @r.to_f
|
113
|
+
m = 1.0 - @g.to_f
|
114
|
+
y = 1.0 - @b.to_f
|
115
|
+
|
116
|
+
k = [c, m, y].min
|
117
|
+
k = k - (k * brightness)
|
118
|
+
|
119
|
+
c = [1.0, [0.0, c - k].max].min
|
120
|
+
m = [1.0, [0.0, m - k].max].min
|
121
|
+
y = [1.0, [0.0, y - k].max].min
|
122
|
+
k = [1.0, [0.0, k].max].min
|
123
|
+
|
124
|
+
Color::CMYK.from_fraction(c, m, y, k)
|
125
|
+
end
|
106
126
|
|
107
|
-
|
108
|
-
|
109
|
-
|
127
|
+
def to_rgb(ignored = nil)
|
128
|
+
self
|
129
|
+
end
|
110
130
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
131
|
+
# Lighten the RGB hue by the stated percent.
|
132
|
+
def lighten_by(percent)
|
133
|
+
mix_with(White, percent)
|
134
|
+
end
|
115
135
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
136
|
+
# Darken the RGB hue by the stated percent.
|
137
|
+
def darken_by(percent)
|
138
|
+
mix_with(Black, percent)
|
139
|
+
end
|
120
140
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
141
|
+
# Mix the mask colour (which must be an RGB object) with the current
|
142
|
+
# colour at the stated opacity percentage (0 .. 100).
|
143
|
+
def mix_with(mask, opacity)
|
144
|
+
opacity /= 100.0
|
145
|
+
rgb = self.dup
|
126
146
|
|
127
|
-
|
128
|
-
|
129
|
-
|
147
|
+
rgb.r = (@r * opacity) + (mask.r * (1 - opacity))
|
148
|
+
rgb.g = (@g * opacity) + (mask.g * (1 - opacity))
|
149
|
+
rgb.b = (@b * opacity) + (mask.b * (1 - opacity))
|
130
150
|
|
131
|
-
|
132
|
-
|
151
|
+
rgb
|
152
|
+
end
|
133
153
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
end
|
154
|
+
# Returns the YIQ (NTSC) colour encoding of the RGB value.
|
155
|
+
def to_yiq
|
156
|
+
y = (@r * 0.299) + (@g * 0.587) + (@b * 0.114)
|
157
|
+
i = (@r * 0.596) + (@g * -0.275) + (@b * -0.321)
|
158
|
+
q = (@r * 0.212) + (@g * -0.523) + (@b * 0.311)
|
159
|
+
Color::YIQ.from_fraction(y, i, q)
|
160
|
+
end
|
142
161
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
162
|
+
# Returns the brightness value for a colour, a number between 0 and
|
163
|
+
# 1. Based on the Y value of YIQ encoding, representing luminosity, or
|
164
|
+
# perceived brightness.
|
165
|
+
def brightness
|
166
|
+
to_yiq.y
|
167
|
+
end
|
168
|
+
alias to_grayscale brightness
|
169
|
+
alias to_greyscale to_grayscale
|
149
170
|
|
150
|
-
|
171
|
+
attr_accessor :r, :g, :b
|
151
172
|
|
152
|
-
|
153
|
-
|
154
|
-
end
|
173
|
+
White = Color::RGB.new(255, 255, 255)
|
174
|
+
Black = Color::RGB.new(0, 0, 0)
|
155
175
|
end
|