coloryze 2.0.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/README +0 -0
- data/bin/coloryze +16 -0
- data/lib/color.rb +16 -0
- data/lib/color/coloryze.rb +225 -0
- data/lib/color/full_palette.rb +158 -0
- data/lib/color/hsb.rb +107 -0
- data/lib/color/palette.rb +92 -0
- data/lib/color/rgb.rb +133 -0
- data/lib/color/sample_palette.rb +78 -0
- data/lib/color/scheme.rb +124 -0
- data/lib/color/util.rb +30 -0
- data/test/color/coloryze_test.rb +90 -0
- data/test/color/full_palette_test.rb +153 -0
- data/test/color/hsb_test.rb +54 -0
- data/test/color/rgb_test.rb +104 -0
- data/test/color/sample_palette_test.rb +64 -0
- data/test/color/scheme_test.rb +95 -0
- data/test/color/util_test.rb +33 -0
- metadata +105 -0
data/README
ADDED
File without changes
|
data/bin/coloryze
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# exec ruby -w -x $0 ${1+"$@"} # -*- ruby -*-
|
3
|
+
#!ruby -w
|
4
|
+
# vim: set filetype=ruby : set sw=2
|
5
|
+
|
6
|
+
dir = File.dirname(File.dirname(File.expand_path(__FILE__)))
|
7
|
+
|
8
|
+
libpath = dir + "/lib"
|
9
|
+
$:.unshift libpath
|
10
|
+
|
11
|
+
require 'color/coloryze'
|
12
|
+
|
13
|
+
Log.output = $stderr
|
14
|
+
|
15
|
+
col = Coloryze.new(ARGV, $stdout)
|
16
|
+
exit(col.exit_status)
|
data/lib/color.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
5
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
6
|
+
|
7
|
+
module Color
|
8
|
+
VERSION = '0.0.1'
|
9
|
+
end
|
10
|
+
|
11
|
+
rbfiles = Dir[File.dirname(__FILE__) + "/color/**/*.rb"]
|
12
|
+
|
13
|
+
rbfiles.sort.each do |rbfile|
|
14
|
+
rootname = rbfile.match(%r{.*/(\w+)\.rb})[1]
|
15
|
+
require "color/" + rootname
|
16
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'color/rgb'
|
5
|
+
require 'color/hsb'
|
6
|
+
require 'color/full_palette'
|
7
|
+
require 'color/sample_palette'
|
8
|
+
require 'color/scheme'
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
require 'riel'
|
12
|
+
|
13
|
+
Log.level = Log::WARN
|
14
|
+
|
15
|
+
class SchemeOption
|
16
|
+
|
17
|
+
attr_accessor :stype, :desc, :cls, :option, :re, :args, :params
|
18
|
+
|
19
|
+
def initialize(stype, desc, cls, *params)
|
20
|
+
@stype = stype
|
21
|
+
@desc = desc
|
22
|
+
@cls = cls
|
23
|
+
@params = params
|
24
|
+
@option = '--' + stype + "=" + params.collect { |arg| arg.to_s.upcase }.join(',')
|
25
|
+
restr = '^' + '--' + stype + "=" + params.collect { |arg| arg == :hue ? '(\#?\w+)' : '(\d+)' }.join(',') + '$' # '$
|
26
|
+
@re = Regexp.new(restr)
|
27
|
+
@args = Array.new
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_args(args)
|
31
|
+
(0 ... args.length).each do |idx|
|
32
|
+
if @params[idx] == :hue
|
33
|
+
@args << create_hue(args[idx])
|
34
|
+
else
|
35
|
+
@args << args[idx].to_i
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_hue(val)
|
41
|
+
if Color::RGB.matches_rgb_string?(val)
|
42
|
+
Color::RGB.new(val).to_hsb.hue
|
43
|
+
elsif md = %r{^\d+$}.match(val)
|
44
|
+
val.to_i
|
45
|
+
else
|
46
|
+
raise RuntimeErro.new("invalid value for hue: #{val}")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
[ @stype, @desc, @cls, @re ].join(" ")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Coloryze
|
56
|
+
include Loggable
|
57
|
+
|
58
|
+
VERSION = "2.0.0"
|
59
|
+
|
60
|
+
attr_reader :exit_status
|
61
|
+
|
62
|
+
def initialize(args, outio = $stdout, errio = $stderr)
|
63
|
+
info "args: #{args}"
|
64
|
+
|
65
|
+
@exit_status = 0
|
66
|
+
@scheme_options = Array.new
|
67
|
+
|
68
|
+
_add_option("monochromatic", "display one hue", Color::Monochromatic, :hue)
|
69
|
+
_add_option("split-complementary", "display hue and two complements near 180 degrees", Color::SplitComplementary, :hue, :deg)
|
70
|
+
_add_option("double-complementary", "display two hues and their two complements", Color::DoubleComplementary, :hue, :hue)
|
71
|
+
_add_option("complementary", "display hues at 180 degrees from each other", Color::Complementary, :hue)
|
72
|
+
_add_option("analogous", "display three hues near each other", Color::Analogous, :hue, :deg)
|
73
|
+
_add_option("triadic", "display three equidistant hues", Color::Triadic, :hue)
|
74
|
+
_add_option("hues", "display colors for the generated hues (no scheme applied)", Color::Hues, :start, :end, :int)
|
75
|
+
|
76
|
+
output_type = :html
|
77
|
+
sample = nil
|
78
|
+
total_sample = nil
|
79
|
+
|
80
|
+
@scheme_options.each do |sopt|
|
81
|
+
# info "sopt: #{sopt}"
|
82
|
+
end
|
83
|
+
|
84
|
+
sopt = nil
|
85
|
+
scheme_args = Array.new
|
86
|
+
|
87
|
+
params = {
|
88
|
+
:background => nil,
|
89
|
+
:saturation_start => nil,
|
90
|
+
:saturation_end => nil,
|
91
|
+
:saturation_step => nil,
|
92
|
+
:brightness_start => nil,
|
93
|
+
:brightness_end => nil,
|
94
|
+
:brightness_step => nil,
|
95
|
+
}
|
96
|
+
|
97
|
+
args.each do |arg|
|
98
|
+
info "arg: #{arg}"
|
99
|
+
|
100
|
+
case arg
|
101
|
+
when %r{--(saturation|brightness)=(\d+),(\d+),(\d+)}
|
102
|
+
md = Regexp.last_match
|
103
|
+
fieldname = md[1]
|
104
|
+
%w{ _start _end _step }.each_with_index do |fieldsuffix, idx|
|
105
|
+
field = (fieldname + fieldsuffix).intern
|
106
|
+
params[field] = md[idx + 2].to_i
|
107
|
+
end
|
108
|
+
# not supported
|
109
|
+
# when %r{--background}
|
110
|
+
# args[:background] = md[1]
|
111
|
+
when %r{--output=(\w+)}
|
112
|
+
md = Regexp.last_match
|
113
|
+
output_type = md[1].intern
|
114
|
+
when "--version"
|
115
|
+
show_version(outio)
|
116
|
+
@exit_status = 0
|
117
|
+
return
|
118
|
+
when "--verbose"
|
119
|
+
Log.level = Log::DEBUG
|
120
|
+
when %r{--sample=(\d+)}
|
121
|
+
md = Regexp.last_match
|
122
|
+
sample = md[1].to_i
|
123
|
+
when %r{--total-sample=(\d+)}
|
124
|
+
md = Regexp.last_match
|
125
|
+
total_sample = md[1].to_i
|
126
|
+
when "--help", "--usage"
|
127
|
+
show_usage(outio)
|
128
|
+
@exit_status = 0
|
129
|
+
return
|
130
|
+
else
|
131
|
+
md = nil
|
132
|
+
if sopt
|
133
|
+
$stderr.puts "error: invalid argument: #{arg}"
|
134
|
+
@sxit_status = 1
|
135
|
+
elsif sopt = @scheme_options.detect { |so| md = so.re.match(arg) }
|
136
|
+
sopt.set_args(md[1 .. -1])
|
137
|
+
scheme_args.concat(md[1 .. -1])
|
138
|
+
|
139
|
+
# add process for scheme without the right parameters
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
unless sopt
|
145
|
+
# check for invalid scheme parameters
|
146
|
+
|
147
|
+
args.each do |arg|
|
148
|
+
@scheme_options.each do |so|
|
149
|
+
if arg.index("--" + so.stype)
|
150
|
+
info "matched #{so}"
|
151
|
+
errio.puts "error: scheme '#{so.stype}' requires " + so.params.collect { |p| p.to_s }.join(",")
|
152
|
+
@exit_status = 1
|
153
|
+
return
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
unless sopt
|
160
|
+
show_usage(outio)
|
161
|
+
@exit_status = 1
|
162
|
+
return
|
163
|
+
end
|
164
|
+
|
165
|
+
info "sopt: #{sopt}"
|
166
|
+
info "scheme_args: #{scheme_args}"
|
167
|
+
|
168
|
+
hues = sopt.cls.new(*sopt.args).hues
|
169
|
+
|
170
|
+
info "hues: #{hues}"
|
171
|
+
info "params: #{params}"
|
172
|
+
|
173
|
+
info "sample: #{sample}"
|
174
|
+
info "total_sample: #{total_sample}"
|
175
|
+
|
176
|
+
palette_cls = if sample || total_sample
|
177
|
+
# yes, a mismatch between *sample and *samples ... legacy option.
|
178
|
+
params[:samples] = sample
|
179
|
+
params[:total_samples] = total_sample
|
180
|
+
Color::SamplePalette
|
181
|
+
else
|
182
|
+
Color::FullPalette
|
183
|
+
end
|
184
|
+
|
185
|
+
palette = palette_cls.new(hues, params)
|
186
|
+
info "palette: #{palette}"
|
187
|
+
if output_type == :html
|
188
|
+
palette.print_as_html(outio)
|
189
|
+
else
|
190
|
+
palette.print_as_text(outio)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def show_version(io)
|
195
|
+
io.puts "coloryze, version #{VERSION}"
|
196
|
+
io.puts "Written by Jeff Pace (jpace@incava.org)"
|
197
|
+
io.puts "Released under the GNU Public License."
|
198
|
+
end
|
199
|
+
|
200
|
+
def show_usage(io)
|
201
|
+
io.puts "usage: coloryze [options]"
|
202
|
+
io.puts "options:"
|
203
|
+
options = Array.new
|
204
|
+
options << [ "--help, --usage", "display this help message" ]
|
205
|
+
@scheme_options.each do |sopt|
|
206
|
+
options << [ sopt.option, sopt.desc ]
|
207
|
+
end
|
208
|
+
options << [ "--sample=NUM", "select only NUM colors per hue, chosen randomly" ]
|
209
|
+
options << [ "--total-sample=NUM", "select only NUM total colors, chosen randomly" ]
|
210
|
+
options << [ "--saturation=START,END,INT", "set the saturation start, end, and interval" ]
|
211
|
+
options << [ "--brightness=START,END,INT", "set the brightness start, end, and interval" ]
|
212
|
+
options << [ "--output=TYPE", "set the output type, \"text\" (the default) or \"html\"" ]
|
213
|
+
options << [ "--verbose", "produce debugging output" ]
|
214
|
+
options << [ "--version", "display the version and exit"]
|
215
|
+
|
216
|
+
options.each do |opt|
|
217
|
+
io.printf " %-30s %s\n", *opt
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def _add_option(stype, desc, cls, *params)
|
222
|
+
@scheme_options << SchemeOption.new(stype, desc, cls, *params)
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'color/hsb'
|
5
|
+
require 'color/rgb'
|
6
|
+
require 'color/util'
|
7
|
+
require 'color/palette'
|
8
|
+
|
9
|
+
# shows a set of colors, in text and html
|
10
|
+
|
11
|
+
module Color
|
12
|
+
|
13
|
+
class FullPalette < Palette
|
14
|
+
|
15
|
+
def initialize(hues, args = Hash.new)
|
16
|
+
super(args)
|
17
|
+
|
18
|
+
# hue => saturation => brightness => rgb
|
19
|
+
@colors = Array.new
|
20
|
+
|
21
|
+
hues.each do |hue|
|
22
|
+
(saturation_start .. saturation_end).step(saturation_step) do |sat|
|
23
|
+
(brightness_start .. brightness_end).step(brightness_step) do |brt|
|
24
|
+
hsb = HSB.new hue, sat / 100.0, brt / 100.0
|
25
|
+
@colors << hsb
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def colors
|
32
|
+
@colors
|
33
|
+
end
|
34
|
+
|
35
|
+
def puts_indented(io, level, msg)
|
36
|
+
io.puts((' ' * (4 * level)) + msg)
|
37
|
+
end
|
38
|
+
|
39
|
+
def print_html_tables(io = $stdout)
|
40
|
+
n_columns = 1 + (@brightness_end - @brightness_start) / @brightness_step
|
41
|
+
|
42
|
+
# want the output to be:
|
43
|
+
|
44
|
+
# +-------------------------------------------------------+
|
45
|
+
# + hue[0] +
|
46
|
+
# + +-----------------------------------------------------+
|
47
|
+
# + + sat[0] +
|
48
|
+
# + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|
49
|
+
# + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b +
|
50
|
+
# + + + + + + + + + + + + + + +
|
51
|
+
# + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|
52
|
+
# + + sat[1] +
|
53
|
+
# + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|
54
|
+
# + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b +
|
55
|
+
# + + + + + + + + + + + + + + +
|
56
|
+
# + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|
57
|
+
# +-------------------------------------------------------+
|
58
|
+
# + hue[1] +
|
59
|
+
# + +-----------------------------------------------------+
|
60
|
+
# + + sat[0] +
|
61
|
+
# + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|
62
|
+
# + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b +
|
63
|
+
# + + + + + + + + + + + + + + +
|
64
|
+
# + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|
65
|
+
# + + sat[1] +
|
66
|
+
# + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|
67
|
+
# + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b +
|
68
|
+
# + + + + + + + + + + + + + + +
|
69
|
+
# + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|
70
|
+
# +-------------------------------------------------------+
|
71
|
+
|
72
|
+
cellwidth = 100 / n_columns
|
73
|
+
|
74
|
+
level = 1
|
75
|
+
|
76
|
+
colors_by_hue.sort.each do |hue, by_saturation|
|
77
|
+
puts_indented io, 1, '<table width="100%">'
|
78
|
+
|
79
|
+
puts_indented io, 2, '<tr>'
|
80
|
+
|
81
|
+
textcolor = @background.nil? || @background.index(%r{[A-Z]\w}) ? "000000" : "FFFFFF"
|
82
|
+
puts_indented io, 3, "<td style=\"color: \##{textcolor};\">hue #{hue} °</td>"
|
83
|
+
|
84
|
+
puts_indented io, 2, '</tr>'
|
85
|
+
|
86
|
+
by_saturation.sort.each do |sat, by_brightness|
|
87
|
+
puts_indented io, 2, '<tr>'
|
88
|
+
puts_indented io, 3, '<td>'
|
89
|
+
|
90
|
+
puts_indented io, 4, '<table width="100%">'
|
91
|
+
puts_indented io, 5, '<tr>'
|
92
|
+
puts_indented io, 6, "<td colspan=#{n_columns}>"
|
93
|
+
|
94
|
+
puts_indented io, 7, "saturation: #{sat}"
|
95
|
+
|
96
|
+
puts_indented io, 6, '</td>'
|
97
|
+
puts_indented io, 5, '</tr>'
|
98
|
+
|
99
|
+
puts_indented io, 5, '<tr>'
|
100
|
+
|
101
|
+
by_brightness.sort.reverse.each do |brt, hsb|
|
102
|
+
rgbstr = sprintf("%06x", hsb.to_rgb)
|
103
|
+
|
104
|
+
puts_indented io, 6, "<td style=\"width: #{cellwidth}%; vertical-align: bottom; border:2px outset; border-collapse:collapse;\">"
|
105
|
+
|
106
|
+
puts_indented io, 7, "<table width=\"100%\" border=\"0\" border-width=\"4px\">"
|
107
|
+
|
108
|
+
stylestr = @background ? " style=\"color: \##{rgbstr};\"" : ""
|
109
|
+
|
110
|
+
text = sprintf "\#%s; b: %3.2f", rgbstr, brt
|
111
|
+
|
112
|
+
puts_indented io, 8, '<tr><td' + stylestr + '>' + text + '</td></tr'
|
113
|
+
|
114
|
+
puts_indented io, 8, "<tr><td style=\"background-color: \##{rgbstr}; vertical-align: bottom;\"><br> </td></tr>"
|
115
|
+
|
116
|
+
puts_indented io, 7, "</table>"
|
117
|
+
puts_indented io, 6, "</td>"
|
118
|
+
end
|
119
|
+
|
120
|
+
puts_indented io, 5, '</tr>'
|
121
|
+
|
122
|
+
puts_indented io, 4, '</table>'
|
123
|
+
|
124
|
+
puts_indented io, 3, '</td>'
|
125
|
+
puts_indented io, 2, '</tr>'
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
puts_indented io, 1, '</table>'
|
130
|
+
end
|
131
|
+
|
132
|
+
return nil if true
|
133
|
+
|
134
|
+
|
135
|
+
colors_by_hue.sort.each do |hue, by_saturation|
|
136
|
+
print_html_hue_line(io, hue, n_columns)
|
137
|
+
|
138
|
+
io.puts "<table width=\"100%\">"
|
139
|
+
io.puts " <tr>"
|
140
|
+
|
141
|
+
by_saturation.sort.each do |sat, by_brightness|
|
142
|
+
by_brightness.sort.reverse.each do |brt, hsb|
|
143
|
+
io.puts " <tr>"
|
144
|
+
|
145
|
+
# this is one color per row, for now
|
146
|
+
print_html_color(io, sat, brt, hsb.to_rgb, 100 / n_columns)
|
147
|
+
|
148
|
+
io.puts " </tr>"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
io.puts "</table>"
|
152
|
+
io.puts "<br/>"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
data/lib/color/hsb.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'color/rgb'
|
5
|
+
require 'color/util'
|
6
|
+
|
7
|
+
module Color
|
8
|
+
|
9
|
+
class HSB
|
10
|
+
attr_accessor :hue, :saturation, :brightness
|
11
|
+
|
12
|
+
def initialize(hue, saturation, brightness)
|
13
|
+
Color::check_constraint(hue, "hue", 0, 360)
|
14
|
+
Color::check_constraint(saturation, "saturation", 0, 1)
|
15
|
+
Color::check_constraint(brightness, "brightness", 0, 1)
|
16
|
+
|
17
|
+
@hue = hue
|
18
|
+
@saturation = saturation
|
19
|
+
@brightness = brightness
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"hue: #{hue}; saturation: #{saturation}; brightness: #{brightness}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def inspect
|
27
|
+
to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
def equal?(other)
|
31
|
+
$stderr.puts "*******"
|
32
|
+
|
33
|
+
hue.equal?(other.hue) &&
|
34
|
+
if cmp == 0
|
35
|
+
cmp = saturation <=> other.saturation
|
36
|
+
if cmp == 0
|
37
|
+
cmp = brightness <=> other.brightness
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
puts "returning: #{cmp}"
|
42
|
+
cmp
|
43
|
+
end
|
44
|
+
|
45
|
+
def <=>(other)
|
46
|
+
cmp = hue <=> other.hue
|
47
|
+
if cmp == 0
|
48
|
+
cmp = saturation <=> other.saturation
|
49
|
+
if cmp == 0
|
50
|
+
cmp = brightness <=> other.brightness
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
cmp
|
55
|
+
end
|
56
|
+
|
57
|
+
def floats_equal?(a, b, threshold)
|
58
|
+
(a - b).abs < 0.0001
|
59
|
+
end
|
60
|
+
|
61
|
+
def ==(other)
|
62
|
+
threshold = 0.0001
|
63
|
+
floats_equal?(hue, other.hue, threshold) && floats_equal?(saturation, other.saturation, threshold) && floats_equal?(brightness, other.brightness, threshold)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Converts HSB (HSV) to RGB. Hue is expected as 0-360; saturation
|
67
|
+
# and brightness (value) as 0.0-1.0. Returns an RGB object.
|
68
|
+
def to_rgb
|
69
|
+
red = green = blue = nil
|
70
|
+
|
71
|
+
if saturation == 0
|
72
|
+
red = green = blue = brightness * 255
|
73
|
+
else
|
74
|
+
hi = (hue / 60.0).to_i
|
75
|
+
f = (hue / 60.0) - hi
|
76
|
+
p = brightness * (1 - saturation)
|
77
|
+
q = brightness * (1 - saturation * f)
|
78
|
+
t = brightness * (1 - saturation * (1 - f))
|
79
|
+
|
80
|
+
red, green, blue = case hi
|
81
|
+
when 0
|
82
|
+
[ brightness, t, p ]
|
83
|
+
when 1
|
84
|
+
[ q, brightness, p ]
|
85
|
+
when 2
|
86
|
+
[ p, brightness, t ]
|
87
|
+
when 3
|
88
|
+
[ p, q, brightness ]
|
89
|
+
when 4
|
90
|
+
[ t, p, brightness ]
|
91
|
+
when 5
|
92
|
+
[ brightness, p, q ]
|
93
|
+
else
|
94
|
+
raise "error: hue: #{hue}; hi: #{hi}"
|
95
|
+
end
|
96
|
+
|
97
|
+
red *= 255
|
98
|
+
green *= 255
|
99
|
+
blue *= 255
|
100
|
+
end
|
101
|
+
|
102
|
+
RGB.new red, green, blue
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|