colormath 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/colormath.rb +28 -0
- data/lib/colormath/blend.rb +23 -0
- data/lib/colormath/color.rb +36 -0
- data/lib/colormath/color/hsl.rb +78 -0
- data/lib/colormath/color/rgb.rb +63 -0
- data/lib/colormath/version.rb +9 -0
- data/test/blend_test.rb +33 -0
- data/test/conversion_test.rb +104 -0
- data/test/hex_decoding_test.rb +56 -0
- data/test/hsl_test.rb +44 -0
- data/test/rgb_test.rb +44 -0
- metadata +74 -0
data/lib/colormath.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module ColorMath
|
2
|
+
ParsingError = Class.new(RuntimeError)
|
3
|
+
|
4
|
+
# Instantiate an RGB colour from a 3- or 6-digit hexadecimal representation.
|
5
|
+
# "#abc", "#abcdef", "abc", and "abcdef" are all valid.
|
6
|
+
#
|
7
|
+
# Invalid representations will raise a ParsingError.
|
8
|
+
#
|
9
|
+
def hex_color(s)
|
10
|
+
if m = s.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i)
|
11
|
+
RGB.new( m[1].to_i(16) / 255.0,
|
12
|
+
m[2].to_i(16) / 255.0,
|
13
|
+
m[3].to_i(16) / 255.0 )
|
14
|
+
elsif m = s.match(/^#?([0-9a-f])([0-9a-f])([0-9a-f])$/i)
|
15
|
+
RGB.new( (m[1] + m[1]).to_i(16) / 255.0,
|
16
|
+
(m[2] + m[2]).to_i(16) / 255.0,
|
17
|
+
(m[3] + m[3]).to_i(16) / 255.0 )
|
18
|
+
else
|
19
|
+
raise ParsingError, "invalid hex sequence '#{s}'"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
extend self
|
24
|
+
end
|
25
|
+
|
26
|
+
require "colormath/color"
|
27
|
+
require "colormath/blend"
|
28
|
+
require "colormath/version"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ColorMath
|
2
|
+
|
3
|
+
# Blend two or more colours and return a new colour.
|
4
|
+
#
|
5
|
+
module Blend
|
6
|
+
|
7
|
+
# Blend ca with cb. alpha represents the proportion of cb,
|
8
|
+
# i.e. alpha = 0 => ca; alpha = 1 => cb.
|
9
|
+
#
|
10
|
+
def alpha(ca, cb, alpha)
|
11
|
+
for_rgb(ca, cb){ |a, b| (alpha * b + (1 - alpha) * a) }
|
12
|
+
end
|
13
|
+
|
14
|
+
extend self
|
15
|
+
|
16
|
+
private
|
17
|
+
def for_rgb(a, b, &blk)
|
18
|
+
RGB.new(*([:red, :green, :blue].map{ |channel|
|
19
|
+
blk.call(a.__send__(channel), b.__send__(channel))
|
20
|
+
}))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module ColorMath
|
2
|
+
|
3
|
+
# Color can be mixed into any class that responds to red, green, and blue, where 0 <= c <= 1
|
4
|
+
#
|
5
|
+
module Color
|
6
|
+
EPSILON = 1/256.0
|
7
|
+
|
8
|
+
# Returns true if the RGB components of the two colours differ by less than EPSILON,
|
9
|
+
# i.e. they are the same when represented in 8 bits.
|
10
|
+
#
|
11
|
+
def ==(other)
|
12
|
+
deltas = [ other.red - self.red,
|
13
|
+
other.green - self.green,
|
14
|
+
other.blue - self.blue ].map{ |e| e.abs }
|
15
|
+
deltas.max < EPSILON
|
16
|
+
end
|
17
|
+
|
18
|
+
# The six-digit hexadecimal representation of the colour, e.g. "#cafe66"
|
19
|
+
#
|
20
|
+
def hex
|
21
|
+
"#%02x%02x%02x" % [red * 0xff, green * 0xff, blue * 0xff]
|
22
|
+
end
|
23
|
+
|
24
|
+
def inspect(*args)
|
25
|
+
"<%s r=%0.3f g=%0.3f b=%0.3f>" % [self.class.to_s, red, green, blue]
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def force_range(v, min, max)
|
30
|
+
[[min, v].max, max].min
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
require "colormath/color/rgb"
|
36
|
+
require "colormath/color/hsl"
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module ColorMath
|
2
|
+
|
3
|
+
# A colour represented and stored as hue, saturation and luminance components
|
4
|
+
#
|
5
|
+
class HSL
|
6
|
+
include Color
|
7
|
+
|
8
|
+
attr_reader :hue, :saturation, :luminance, :alpha
|
9
|
+
|
10
|
+
# Initialize an HSL colour where:
|
11
|
+
# 0 <= h <= 360
|
12
|
+
# 0 <= s <= 1
|
13
|
+
# 0 <= l <= 1
|
14
|
+
#
|
15
|
+
# Values outside these ranges will be clippped.
|
16
|
+
#
|
17
|
+
def initialize(h, s, l)
|
18
|
+
@hue = force_range(h, 0, 360).to_f
|
19
|
+
@saturation = force_range(s, 0, 1).to_f
|
20
|
+
@luminance = force_range(l, 0, 1).to_f
|
21
|
+
end
|
22
|
+
|
23
|
+
# The red component of the colour in RGB representation where 0 <= r <= 1
|
24
|
+
#
|
25
|
+
def red
|
26
|
+
t = component(hk + (1/3.0))
|
27
|
+
end
|
28
|
+
|
29
|
+
# The green component of the colour in RGB representation where 0 <= g <= 1
|
30
|
+
#
|
31
|
+
def green
|
32
|
+
t = component(hk)
|
33
|
+
end
|
34
|
+
|
35
|
+
# The blue component of the colour in RGB representation where 0 <= b <= 1
|
36
|
+
#
|
37
|
+
def blue
|
38
|
+
t = component(hk - (1/3.0))
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def hk
|
43
|
+
hue / 360.0
|
44
|
+
end
|
45
|
+
|
46
|
+
def q
|
47
|
+
@q ||= if luminance < 0.5
|
48
|
+
luminance * (1.0 + saturation)
|
49
|
+
else
|
50
|
+
luminance + saturation - (luminance * saturation)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def p
|
55
|
+
@p ||= 2 * luminance - q
|
56
|
+
end
|
57
|
+
|
58
|
+
def component(t)
|
59
|
+
t = if t < 0
|
60
|
+
t + 1.0
|
61
|
+
elsif t > 1
|
62
|
+
t - 1.0
|
63
|
+
else
|
64
|
+
t
|
65
|
+
end
|
66
|
+
|
67
|
+
if t < (1/6.0)
|
68
|
+
p + ((q - p) * 6.0 * t)
|
69
|
+
elsif (1/6.0) <= t && t < 0.5
|
70
|
+
q
|
71
|
+
elsif 0.5 <= t && t < (2/3.0)
|
72
|
+
p + ((q - p) * 6.0 * (2/3.0 - t))
|
73
|
+
else
|
74
|
+
p
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module ColorMath
|
2
|
+
|
3
|
+
# A colour represented and stored as red, green and blue components
|
4
|
+
#
|
5
|
+
class RGB
|
6
|
+
include Color
|
7
|
+
|
8
|
+
attr_reader :red, :green, :blue
|
9
|
+
|
10
|
+
# Initialize an RGB colour where:
|
11
|
+
# 0 <= r <= 1
|
12
|
+
# 0 <= g <= 1
|
13
|
+
# 0 <= b <= 1
|
14
|
+
#
|
15
|
+
# Values outside these ranges will be clippped.
|
16
|
+
#
|
17
|
+
def initialize(r, g, b)
|
18
|
+
@red = force_range(r, 0, 1).to_f
|
19
|
+
@green = force_range(g, 0, 1).to_f
|
20
|
+
@blue = force_range(b, 0, 1).to_f
|
21
|
+
end
|
22
|
+
|
23
|
+
# The hue component of the colour in HSL representation where 0 <= h < 360
|
24
|
+
#
|
25
|
+
def hue
|
26
|
+
case max
|
27
|
+
when red
|
28
|
+
(60.0 * ((green - blue) / (max - min))) % 360.0
|
29
|
+
when green
|
30
|
+
60.0 * ((blue - red) / (max - min)) + 120.0
|
31
|
+
when blue
|
32
|
+
60.0 * ((red - green) / (max - min)) + 240.0
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# The saturation component of the colour in HSL representation where 0 <= s <= 1
|
37
|
+
#
|
38
|
+
def saturation
|
39
|
+
if max == min
|
40
|
+
0
|
41
|
+
elsif luminance <= 0.5
|
42
|
+
(max - min) / (2.0 * luminance)
|
43
|
+
else
|
44
|
+
(max - min) / (2.0 - 2.0 * luminance)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# The luminance component of the colour in HSL representation where 0 <= l <= 1
|
49
|
+
#
|
50
|
+
def luminance
|
51
|
+
0.5 * (max + min)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def min
|
56
|
+
[red, green, blue].min
|
57
|
+
end
|
58
|
+
|
59
|
+
def max
|
60
|
+
[red, green, blue].max
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/test/blend_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require "test/unit"
|
3
|
+
require "shoulda"
|
4
|
+
require "colormath"
|
5
|
+
|
6
|
+
class AlphaBlendTest < Test::Unit::TestCase
|
7
|
+
def blend(a, b, alpha)
|
8
|
+
ColorMath::Blend.alpha(ColorMath::hex_color(a), ColorMath::hex_color(b), alpha).hex
|
9
|
+
end
|
10
|
+
|
11
|
+
context "with sample colors" do
|
12
|
+
setup do
|
13
|
+
@background = "#ffffff"
|
14
|
+
@foreground = "#862e8b"
|
15
|
+
end
|
16
|
+
|
17
|
+
should "blend 0% sample" do
|
18
|
+
assert_equal @background, blend(@background, @foreground, 0.0)
|
19
|
+
end
|
20
|
+
|
21
|
+
should "blend 10% sample" do
|
22
|
+
assert_equal "#f2eaf3", blend(@background, @foreground, 0.1)
|
23
|
+
end
|
24
|
+
|
25
|
+
should "blend 30% sample" do
|
26
|
+
assert_equal "#dac0dc", blend(@background, @foreground, 0.3)
|
27
|
+
end
|
28
|
+
|
29
|
+
should "blend 100% sample" do
|
30
|
+
assert_equal @foreground, blend(@background, @foreground, 1.0)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require "test/unit"
|
3
|
+
require "shoulda"
|
4
|
+
require "colormath"
|
5
|
+
|
6
|
+
class ConversionTest < Test::Unit::TestCase
|
7
|
+
EPSILON = 1e-2
|
8
|
+
|
9
|
+
EDGE_CASES = [
|
10
|
+
[[1, 0, 0], [ 0, 1, 0.5 ]],
|
11
|
+
[[0.5, 1, 0.5], [120, 1, 0.75]],
|
12
|
+
[[0, 0, 0.5], [240, 1, 0.25]],
|
13
|
+
]
|
14
|
+
|
15
|
+
context "with edge cases" do
|
16
|
+
EDGE_CASES.each do |(r,g,b), (h,s,l)|
|
17
|
+
should "convert RGB(#{r},#{g},#{b}) to HSL(#{h},#{s},#{l})" do
|
18
|
+
c = ColorMath::RGB.new(r, g, b)
|
19
|
+
assert_in_delta h, c.hue, EPSILON
|
20
|
+
assert_in_delta s, c.saturation, EPSILON
|
21
|
+
assert_in_delta l, c.luminance, EPSILON
|
22
|
+
end
|
23
|
+
|
24
|
+
should "convert HSL(#{h},#{s},#{l}) to RGB(#{r},#{g},#{b})" do
|
25
|
+
c = ColorMath::HSL.new(h, s, l)
|
26
|
+
assert_in_delta r, c.red, EPSILON
|
27
|
+
assert_in_delta g, c.green, EPSILON
|
28
|
+
assert_in_delta b, c.blue, EPSILON
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
HSL_SAMPLES = [
|
34
|
+
[267.0, 0.14, 0.17],
|
35
|
+
[322.0, 0.22, 0.54],
|
36
|
+
[211.0, 0.54, 0.19],
|
37
|
+
[347.0, 0.90, 0.38],
|
38
|
+
[184.0, 0.75, 0.13],
|
39
|
+
[177.0, 0.07, 0.14],
|
40
|
+
[ 97.0, 0.93, 0.70],
|
41
|
+
[139.0, 0.04, 0.37],
|
42
|
+
[ 17.0, 0.88, 0.67],
|
43
|
+
[162.0, 0.21, 0.61],
|
44
|
+
[358.0, 0.78, 0.50],
|
45
|
+
[104.0, 0.78, 0.63],
|
46
|
+
[280.0, 0.38, 0.66],
|
47
|
+
[298.0, 0.06, 0.72],
|
48
|
+
[162.0, 0.39, 0.86],
|
49
|
+
[305.0, 0.55, 0.16],
|
50
|
+
[248.0, 0.80, 0.84],
|
51
|
+
[109.0, 0.23, 0.23],
|
52
|
+
[328.0, 0.88, 0.88],
|
53
|
+
[ 26.0, 0.99, 0.52],
|
54
|
+
]
|
55
|
+
|
56
|
+
context "roundtripping HSL -> RGB -> HSL" do
|
57
|
+
HSL_SAMPLES.each do |h,s,l|
|
58
|
+
should "roundtrip HSL(#{h},#{s},#{l})" do
|
59
|
+
hsl = ColorMath::HSL.new(h, s, l)
|
60
|
+
rgb = ColorMath::RGB.new(hsl.red, hsl.green, hsl.blue)
|
61
|
+
|
62
|
+
assert_in_delta h, rgb.hue, EPSILON
|
63
|
+
assert_in_delta s, rgb.saturation, EPSILON
|
64
|
+
assert_in_delta l, rgb.luminance, EPSILON
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
RGB_SAMPLES = [
|
70
|
+
[0.19, 0.41, 0.70],
|
71
|
+
[0.13, 0.22, 0.28],
|
72
|
+
[0.45, 0.44, 0.24],
|
73
|
+
[0.96, 0.94, 0.24],
|
74
|
+
[0.76, 0.01, 0.16],
|
75
|
+
[0.55, 0.96, 0.01],
|
76
|
+
[0.07, 0.61, 0.73],
|
77
|
+
[0.05, 0.58, 0.51],
|
78
|
+
[0.43, 0.05, 0.24],
|
79
|
+
[0.66, 0.80, 0.80],
|
80
|
+
[0.54, 0.35, 0.10],
|
81
|
+
[0.12, 0.41, 0.27],
|
82
|
+
[0.78, 0.32, 0.93],
|
83
|
+
[0.52, 0.15, 0.43],
|
84
|
+
[0.17, 0.26, 0.53],
|
85
|
+
[0.19, 0.96, 0.66],
|
86
|
+
[0.54, 0.36, 0.84],
|
87
|
+
[0.12, 0.89, 0.60],
|
88
|
+
[0.75, 0.03, 0.83],
|
89
|
+
[0.09, 0.35, 0.83],
|
90
|
+
]
|
91
|
+
|
92
|
+
context "roundtripping RGB -> HSL -> RGB" do
|
93
|
+
RGB_SAMPLES.each do |r,g,b|
|
94
|
+
should "roundtrip RGB(#{r},#{g},#{b})" do
|
95
|
+
rgb = ColorMath::RGB.new(r, g, b)
|
96
|
+
hsl = ColorMath::HSL.new(rgb.hue, rgb.saturation, rgb.luminance)
|
97
|
+
|
98
|
+
assert_in_delta r, hsl.red, EPSILON
|
99
|
+
assert_in_delta g, hsl.green, EPSILON
|
100
|
+
assert_in_delta b, hsl.blue, EPSILON
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require "test/unit"
|
3
|
+
require "shoulda"
|
4
|
+
require "colormath"
|
5
|
+
|
6
|
+
class HexDecodingTest < Test::Unit::TestCase
|
7
|
+
EPSILON = 1e-3
|
8
|
+
|
9
|
+
should "decode 6-digit hex string with leading #" do
|
10
|
+
c = ColorMath::hex_color("#abcd54")
|
11
|
+
assert_in_delta (0xab / 255.0), c.red, EPSILON
|
12
|
+
assert_in_delta (0xcd / 255.0), c.green, EPSILON
|
13
|
+
assert_in_delta (0x54 / 255.0), c.blue, EPSILON
|
14
|
+
end
|
15
|
+
|
16
|
+
should "decode 6-digit hex string without leading #" do
|
17
|
+
c = ColorMath::hex_color("abcd54")
|
18
|
+
assert_in_delta (0xab / 255.0), c.red, EPSILON
|
19
|
+
assert_in_delta (0xcd / 255.0), c.green, EPSILON
|
20
|
+
assert_in_delta (0x54 / 255.0), c.blue, EPSILON
|
21
|
+
end
|
22
|
+
|
23
|
+
should "decode 3-digit hex string with leading #" do
|
24
|
+
c = ColorMath::hex_color("#a1c")
|
25
|
+
assert_in_delta (0xaa / 255.0), c.red, EPSILON
|
26
|
+
assert_in_delta (0x11 / 255.0), c.green, EPSILON
|
27
|
+
assert_in_delta (0xcc / 255.0), c.blue, EPSILON
|
28
|
+
end
|
29
|
+
|
30
|
+
should "decode 3-digit hex string without leading #" do
|
31
|
+
c = ColorMath::hex_color("a1c")
|
32
|
+
assert_in_delta (0xaa / 255.0), c.red, EPSILON
|
33
|
+
assert_in_delta (0x11 / 255.0), c.green, EPSILON
|
34
|
+
assert_in_delta (0xcc / 255.0), c.blue, EPSILON
|
35
|
+
end
|
36
|
+
|
37
|
+
should "decode 6-digit hex string in upper case" do
|
38
|
+
c = ColorMath::hex_color("#ABCD54")
|
39
|
+
assert_in_delta (0xab / 255.0), c.red, EPSILON
|
40
|
+
assert_in_delta (0xcd / 255.0), c.green, EPSILON
|
41
|
+
assert_in_delta (0x54 / 255.0), c.blue, EPSILON
|
42
|
+
end
|
43
|
+
|
44
|
+
should "decode 3-digit hex string in upper case" do
|
45
|
+
c = ColorMath::hex_color("#A1C")
|
46
|
+
assert_in_delta (0xaa / 255.0), c.red, EPSILON
|
47
|
+
assert_in_delta (0x11 / 255.0), c.green, EPSILON
|
48
|
+
assert_in_delta (0xcc / 255.0), c.blue, EPSILON
|
49
|
+
end
|
50
|
+
|
51
|
+
should "raise a ParsingError when the hex string is invalid" do
|
52
|
+
assert_raises ColorMath::ParsingError do
|
53
|
+
ColorMath::hex_color("kjhhdfs")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/test/hsl_test.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require "test/unit"
|
3
|
+
require "shoulda"
|
4
|
+
require "colormath"
|
5
|
+
|
6
|
+
class HSLTest < Test::Unit::TestCase
|
7
|
+
should "be equal if initialized with same values" do
|
8
|
+
assert_equal ColorMath::HSL.new(123, 0.5, 0.7), ColorMath::HSL.new(123, 0.5, 0.7)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "not be equal if initialized with different values" do
|
12
|
+
assert_not_equal ColorMath::HSL.new(124, 0.4, 0.8), ColorMath::HSL.new(123, 0.5, 0.7)
|
13
|
+
end
|
14
|
+
|
15
|
+
should "force hue >= 0" do
|
16
|
+
c = ColorMath::HSL.new(-2, 0, 0)
|
17
|
+
assert_equal 0, c.hue
|
18
|
+
end
|
19
|
+
|
20
|
+
should "force hue <= 360" do
|
21
|
+
c = ColorMath::HSL.new(361, 0, 0)
|
22
|
+
assert_equal 360, c.hue
|
23
|
+
end
|
24
|
+
|
25
|
+
should "force saturation >= 0" do
|
26
|
+
c = ColorMath::HSL.new(0, -1, 0)
|
27
|
+
assert_equal 0, c.saturation
|
28
|
+
end
|
29
|
+
|
30
|
+
should "force saturation <= 1" do
|
31
|
+
c = ColorMath::HSL.new(0, 1.1, 0)
|
32
|
+
assert_equal 1, c.saturation
|
33
|
+
end
|
34
|
+
|
35
|
+
should "force luminance >= 0" do
|
36
|
+
c = ColorMath::HSL.new(0, 0, -1)
|
37
|
+
assert_equal 0, c.luminance
|
38
|
+
end
|
39
|
+
|
40
|
+
should "force luminance <= 1" do
|
41
|
+
c = ColorMath::HSL.new(0, 0, 1.1)
|
42
|
+
assert_equal 1, c.luminance
|
43
|
+
end
|
44
|
+
end
|
data/test/rgb_test.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require "test/unit"
|
3
|
+
require "shoulda"
|
4
|
+
require "colormath"
|
5
|
+
|
6
|
+
class RGBTest < Test::Unit::TestCase
|
7
|
+
should "be equal if initialized with same values" do
|
8
|
+
assert_equal ColorMath::RGB.new(0.3, 0.5, 0.7), ColorMath::RGB.new(0.3, 0.5, 0.7)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "not be equal if initialized with different values" do
|
12
|
+
assert_not_equal ColorMath::RGB.new(0.5, 0.4, 0.8), ColorMath::RGB.new(0.3, 0.5, 0.7)
|
13
|
+
end
|
14
|
+
|
15
|
+
should "force red >= 0" do
|
16
|
+
c = ColorMath::HSL.new(-2, 0, 0)
|
17
|
+
assert_equal 0, c.red
|
18
|
+
end
|
19
|
+
|
20
|
+
should "force red <= 1" do
|
21
|
+
c = ColorMath::RGB.new(1.1, 0, 0)
|
22
|
+
assert_equal 1, c.red
|
23
|
+
end
|
24
|
+
|
25
|
+
should "force green >= 0" do
|
26
|
+
c = ColorMath::RGB.new(0, -1, 0)
|
27
|
+
assert_equal 0, c.green
|
28
|
+
end
|
29
|
+
|
30
|
+
should "force green <= 1" do
|
31
|
+
c = ColorMath::RGB.new(0, 1.1, 0)
|
32
|
+
assert_equal 1, c.green
|
33
|
+
end
|
34
|
+
|
35
|
+
should "force blue >= 0" do
|
36
|
+
c = ColorMath::RGB.new(0, 0, -1)
|
37
|
+
assert_equal 0, c.blue
|
38
|
+
end
|
39
|
+
|
40
|
+
should "force blue <= 1" do
|
41
|
+
c = ColorMath::RGB.new(0, 0, 1.1)
|
42
|
+
assert_equal 1, c.blue
|
43
|
+
end
|
44
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: colormath
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Battley
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-09 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: shoulda
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: pbattley@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- test/blend_test.rb
|
35
|
+
- test/conversion_test.rb
|
36
|
+
- test/hex_decoding_test.rb
|
37
|
+
- test/hsl_test.rb
|
38
|
+
- test/rgb_test.rb
|
39
|
+
- lib/colormath/blend.rb
|
40
|
+
- lib/colormath/color/hsl.rb
|
41
|
+
- lib/colormath/color/rgb.rb
|
42
|
+
- lib/colormath/color.rb
|
43
|
+
- lib/colormath/version.rb
|
44
|
+
- lib/colormath.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage:
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.3.4
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: Colour manipulation library for Ruby
|
73
|
+
test_files: []
|
74
|
+
|