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 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 install.rb
3
+ % ruby setup.rb
4
4
 
5
5
  Alternatively, you can use the RubyGem version of color-tools available as
6
- color-tools-1.1.0.gem from the usual sources.
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 CMYK colour support to
3
- applications that require it. It provides 148 named RGB colours that are
4
- commonly supported and used in HTML, colour manipulation operations, and
5
- a monochromatic contrasting palette generator. With version 1.1, the
6
- ability to read and use GIMP colour palette definition files has been
7
- added.
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
- in all copies or substantial portions of the Software.
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
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
37
- ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
38
- SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
39
- OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
40
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
41
- OTHER DEALINGS IN THE SOFTWARE.
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.read(dd)
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
@@ -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)
@@ -5,69 +5,134 @@
5
5
  # http://rubyforge.org/ruby-pdf/
6
6
  #++
7
7
 
8
- require 'color/rgb'
8
+ # An CMYK colour object.
9
+ class Color::CMYK
10
+ PDF_FORMAT_STR = "%.3f %.3f %.3f %.3f %s"
9
11
 
10
- module Color
11
- # An CMYK colour object.
12
- class CMYK
13
- PDF_FORMAT_STR = "%.3f %.3f %.3f %.3f %s"
14
-
15
- def ==(other)
16
- other = other.to_cmyk if other.kind_of?(Color::RGB)
17
- other.kind_of?(Color::CMYK) and
18
- (@c == other.c) and
19
- (@m == other.m) and
20
- (@y == other.y) and
21
- (@k == other.k)
22
- end
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
- # Creates a CMYK colour object from fractional values 0 .. 1.
25
- def self.from_fraction(c = 0, m = 0, y = 0, k = 0)
26
- colour = Color::CMYK.new
27
- colour.instance_variable_set(:@c, c)
28
- colour.instance_variable_set(:@m, m)
29
- colour.instance_variable_set(:@y, y)
30
- colour.instance_variable_set(:@k, k)
31
- colour
32
- end
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
- # Creates a CMYK colour object from percentages.
35
- def initialize(c = 0, m = 0, y = 0, k = 0)
36
- @c = c / 100.0
37
- @m = m / 100.0
38
- @y = y / 100.0
39
- @k = k / 100.0
40
- end
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
- # Present the colour as a fill colour string for PDF.
43
- def pdf_fill
44
- PDF_FORMAT_STR % [ @c, @m, @y, @k, "k" ]
45
- end
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
- # Present the colour as a stroke colour string for PDF.
48
- def pdf_stroke
49
- PDF_FORMAT_STR % [ @c, @m, @y, @k, "K" ]
50
- end
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
- # Present the colour as an HTML/CSS colour string.
53
- def html
54
- to_rgb.html
55
- end
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
- # Convert the CMYK colour to RGB. Note that colour experts strongly
58
- # suggest that this is a *bad* idea, as CMYK represents percentages of
59
- # inks, not mixed colour intensities like RGB.
60
- def to_rgb
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
- def to_cmyk
68
- self.dup
69
- end
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
- attr_accessor :c, :m, :y, :k
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
@@ -5,151 +5,171 @@
5
5
  # http://rubyforge.org/ruby-pdf/
6
6
  #++
7
7
 
8
- require 'color/cmyk'
9
-
10
- module Color
11
- # An RGB colour object.
12
- class RGB
13
- # The format required to present the colour to a PDF document.
14
- PDF_FORMAT_STR = "%.3f %.3f %.3f %s"
15
-
16
- class << self
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
- def ==(other)
49
- other = other.to_rgb
50
- other.kind_of?(Color::RGB) and
51
- (@r == other.r) and
52
- (@g == other.g) and
53
- (@b == other.b)
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 the standard range 0 .. 255.
57
- def initialize(r = 0, g = 0, b = 0)
58
- @r = r / 255.0
59
- @g = g / 255.0
60
- @b = b / 255.0
61
- end
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
- # Present the colour as a fill colour string for PDF.
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
- # Present the colour as a stroke colour string for PDF.
69
- def pdf_stroke
70
- PDF_FORMAT_STR % [ @r, @g, @b, "RG" ]
71
- end
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
- # Present the colour as an HTML/CSS colour string.
74
- def html
75
- r = (@r * 255).round
76
- r = 255 if r > 255
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
- g = (@g * 255).round
79
- g = 255 if g > 255
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
- b = (@b * 255).round
82
- b = 255 if b > 255
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
- "#%02x%02x%02x" % [ r, g, b ]
85
- end
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
- # Convert the RGB colour to CMYK. Note that colour experts strongly
88
- # suggest that this is a *bad* idea, as CMYK represents percentages of
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
- k = 1.0
96
- k = c if c < k
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
- c = (c.to_f - k.to_f) / (1.0 - k.to_f)
101
- m = (m.to_f - k.to_f) / (1.0 - k.to_f)
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
- Color::CMYK.new(c, m, y, k)
105
- end
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
- def to_rgb
108
- self.dup
109
- end
127
+ def to_rgb(ignored = nil)
128
+ self
129
+ end
110
130
 
111
- # Lighten the RGB hue by the stated percent.
112
- def lighten_by(percent)
113
- mix_with(White, percent)
114
- end
131
+ # Lighten the RGB hue by the stated percent.
132
+ def lighten_by(percent)
133
+ mix_with(White, percent)
134
+ end
115
135
 
116
- # Darken the RGB hue by the stated percent.
117
- def darken_by(percent)
118
- mix_with(Black, percent)
119
- end
136
+ # Darken the RGB hue by the stated percent.
137
+ def darken_by(percent)
138
+ mix_with(Black, percent)
139
+ end
120
140
 
121
- # Mix the mask colour (which must be an RGB object) with the current
122
- # colour at the stated opacity percentage (0 .. 100).
123
- def mix_with(mask, opacity)
124
- opacity /= 100.0
125
- rgb = self.dup
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
- rgb.r = (@r * opacity) + (mask.r * (1 - opacity))
128
- rgb.g = (@g * opacity) + (mask.g * (1 - opacity))
129
- rgb.b = (@b * opacity) + (mask.b * (1 - opacity))
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
- rgb
132
- end
151
+ rgb
152
+ end
133
153
 
134
- # Returns the YIQ (NTSC) colour encoding of the RGB value.
135
- def to_yiq
136
- {
137
- :y => (@r * 0.299) + (@g * 0.587) + (@b * 0.114),
138
- :i => (@r * 0.596) + (@g * -0.275) + (@b * -0.321),
139
- :q => (@r * 0.212) + (@g * -0.523) + (@b * 0.311),
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
- # Returns the brightness value for a colour, a number between 0 and
144
- # 1. Based on the Y value of YIQ encoding, representing luminosity, or
145
- # perceived brightness.
146
- def brightness
147
- to_yiq[:y]
148
- end
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
- attr_accessor :r, :g, :b
171
+ attr_accessor :r, :g, :b
151
172
 
152
- White = RGB.new(255, 255, 255)
153
- Black = RGB.new(0, 0, 0)
154
- end
173
+ White = Color::RGB.new(255, 255, 255)
174
+ Black = Color::RGB.new(0, 0, 0)
155
175
  end