red-colors 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3587e5433ccb431efbc46112034d3b9f00d40ad58e8389cb4081bf0bdcb3304f
4
- data.tar.gz: 2568105af67abd20c5133a7181194489006eef94cc3c4834d0f3509eaf01c5f9
3
+ metadata.gz: c144d5d89c917428d99401b92513852896b2ff109228d85b2ddac5dd40b89fb4
4
+ data.tar.gz: 8e99f5fadc2068211a0ec92d12ad754ae777efedd23048867c0ad91824fe7a35
5
5
  SHA512:
6
- metadata.gz: d15ae1556244a040ff0822fc739e7dd561d2f29fc9cec04ba68bbc72a1bd6afe097c66fa88f5450bd7f7bce3e89622b34726bdc5e64320255cb6ba71a0c508f7
7
- data.tar.gz: aa96cd5773128f79d48993319d920e7325b4db7520429eb211347abfb375688566b083d049e1e679aa81ca05f545682490d70f2b29beaedcbc6ea1c094c45c50
6
+ metadata.gz: 53491ee2e2c97a99c624d5e4d2fc73d9939f68ee9b27f24f54bcf1f3831f87f8cf2d115d4c8b0499e73e2623ad6e045c714f254a4dc33da55dfdf84213b45903
7
+ data.tar.gz: 1d783343d7536ca570bdbd049d83d92a107450341e03a8f4a390f88abc891d92d67404e198b87ee7555b6abea05610e13f4afcd9421d417c20f1ef3e38be002c
data/README.md CHANGED
@@ -27,6 +27,8 @@ $ gem install red-colors
27
27
 
28
28
  To be described later.
29
29
 
30
+ See the [documentation](https://rubydoc.info/gems/red-colors) for now.
31
+
30
32
  ## License
31
33
 
32
34
  The MIT license. See [`LICENSE.txt`](LICENSE.txt) for details.
data/lib/colors.rb CHANGED
@@ -8,6 +8,7 @@ require_relative "colors/hsla"
8
8
  require_relative "colors/husl"
9
9
  require_relative "colors/rgb"
10
10
  require_relative "colors/rgba"
11
+ require_relative "colors/xterm256"
11
12
  require_relative "colors/xyy"
12
13
  require_relative "colors/xyz"
13
14
 
@@ -148,6 +148,51 @@ module Colors
148
148
  dot_product(RGB2XYZ, srgb_to_linear_srgb(r, g, b))
149
149
  end
150
150
 
151
+ def rgb_to_xterm256(r, g, b)
152
+ i = closest_xterm256_rgb_index(r)
153
+ j = closest_xterm256_rgb_index(g)
154
+ k = closest_xterm256_rgb_index(b)
155
+
156
+ r0 = xterm256_rgb_index_to_rgb_value(i)
157
+ g0 = xterm256_rgb_index_to_rgb_value(j)
158
+ b0 = xterm256_rgb_index_to_rgb_value(k)
159
+ d0 = (r - r0)**2 + (g - g0)**2 + (b - b0)**2
160
+
161
+ l = closest_xterm256_gray_index(r, g, b)
162
+ gr = xterm256_gray_index_to_gray_level(l)
163
+ d1 = (r - gr)**2 + (g - gr)**2 + (b - gr)**2
164
+
165
+ if d0 > d1
166
+ xterm256_gray_index_to_code(l)
167
+ else
168
+ xterm256_rgb_indices_to_code(i, j, k)
169
+ end
170
+ end
171
+
172
+ def xterm256_rgb_index_to_rgb_value(i)
173
+ (i == 0) ? 0 : (40*i + 55)/255.0
174
+ end
175
+
176
+ def closest_xterm256_rgb_index(x)
177
+ ([x*255 - 55, 0].max / 40.0).round
178
+ end
179
+
180
+ def xterm256_gray_index_to_gray_level(i)
181
+ (10*i + 8)/255.0
182
+ end
183
+
184
+ def closest_xterm256_gray_index(r, g, b)
185
+ ((255*(r + g + b) - 24)/30.0).round.clamp(0, 23)
186
+ end
187
+
188
+ def xterm256_rgb_indices_to_code(i, j, k)
189
+ 6*(6*i + j) + k + 16
190
+ end
191
+
192
+ def xterm256_gray_index_to_code(i)
193
+ i + 232
194
+ end
195
+
151
196
  # sRGB -> ???
152
197
 
153
198
  def srgb_to_linear_srgb(r, g, b)
data/lib/colors/rgb.rb CHANGED
@@ -125,6 +125,10 @@ module Colors
125
125
  XYZ.new(*Convert.rgb_to_xyz(r, g, b))
126
126
  end
127
127
 
128
+ def to_xterm256
129
+ Xterm256.new(*Convert.rgb_to_xterm256(r, g, b))
130
+ end
131
+
128
132
  private def canonicalize(r, g, b)
129
133
  if [r, g, b].map(&:class) == [Integer, Integer, Integer]
130
134
  canonicalize_from_integer(r, g, b)
@@ -1,3 +1,3 @@
1
1
  module Colors
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -0,0 +1,56 @@
1
+ module Colors
2
+ class Xterm256 < AbstractColor
3
+ include Helper
4
+
5
+ def initialize(code)
6
+ unless 16 <= code && code <= 255
7
+ raise ArgumentError, "code should be in 16..255, but #{code} is given"
8
+ end
9
+ @code = code
10
+ end
11
+
12
+ attr_reader :code
13
+
14
+ def ==(other)
15
+ case other
16
+ when Xterm256
17
+ code == other.code
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ def to_rgb_components
24
+ if code < 232
25
+ x = code - 16
26
+ x, b = x.divmod(6)
27
+ r, g = x.divmod(6)
28
+ r = 40*r + 55 if r > 0
29
+ g = 40*g + 55 if g > 0
30
+ b = 40*b + 55 if b > 0
31
+ [
32
+ canonicalize_component_from_integer(r, :r),
33
+ canonicalize_component_from_integer(g, :r),
34
+ canonicalize_component_from_integer(b, :r)
35
+ ]
36
+ else
37
+ grey = to_grey_level
38
+ [grey, grey, grey]
39
+ end
40
+ end
41
+
42
+ def to_grey_level
43
+ if code < 232
44
+ r, g, b = to_rgb_components
45
+ x, y, z = Convet.rgb_to_xyz(r, g, b)
46
+ else
47
+ grey = 10*(code - 232) + 8
48
+ canonicalize_component_from_integer(grey, :grey)
49
+ end
50
+ end
51
+
52
+ def to_rgb
53
+ RGB.new(*to_rgb_components)
54
+ end
55
+ end
56
+ end
data/lib/colors/xyz.rb CHANGED
@@ -4,7 +4,7 @@ module Colors
4
4
 
5
5
  EPSILON = (6/29r)**3
6
6
 
7
- KAPPA = (29/3)**3
7
+ KAPPA = (29/3r)**3
8
8
 
9
9
  def initialize(x, y, z)
10
10
  @x, @y, @z = canonicalize(x, y, z)
data/test/test-rgb.rb CHANGED
@@ -318,4 +318,64 @@ class ColorsRGBTest < Test::Unit::TestCase
318
318
  assert_near(Colors::HUSL.new(0r, 0r, 1r),
319
319
  Colors::RGB.new(1r, 1r, 1r).to_husl)
320
320
  end
321
+
322
+ data do
323
+ data_set = {}
324
+ # colors 16-231 are a 6x6x6 color cube
325
+ (0...6).each do |r|
326
+ (0...6).each do |g|
327
+ (0...6).each do |b|
328
+ code = 6*(6*r + g) + b + 16
329
+ red = (r > 0) ? 40*r + 55 : r
330
+ green = (g > 0) ? 40*g + 55 : g
331
+ blue = (b > 0) ? 40*b + 55 : b
332
+ label = "Color #{code} is rgb(#{red}, #{green}, #{blue})"
333
+ data_set[label] = [code, Colors::RGB.new(red, green, blue)]
334
+ end
335
+ end
336
+ end
337
+ # colors 232-256 are grayscale colors
338
+ (0...24).each do |y|
339
+ code = 232 + y
340
+ level = 10*y + 8
341
+ label = "Color #{code} is gray(#{level})"
342
+ data_set[label] = [code, Colors::RGB.new(level, level, level)]
343
+ end
344
+ # Some colors to check cloest color finder
345
+ [
346
+ [ 0, 0, 8, 16 ],
347
+ [ 0, 8, 0, 16 ],
348
+ [ 11, 0, 0, 16 ],
349
+ [ 0, 0, 12, 232 ],
350
+ [ 0, 12, 0, 232 ],
351
+ [ 12, 0, 0, 232 ],
352
+
353
+ [ 0, 0, 75, 17 ],
354
+ [ 0, 75, 0, 22 ],
355
+ [ 75, 0, 0, 52 ],
356
+
357
+ [ 0, 128, 128, 30 ],
358
+ [ 102, 102, 102, 241 ],
359
+ [ 103, 103, 103, 242 ],
360
+ [ 208, 238, 238, 254 ],
361
+ [ 208, 208, 238, 189 ],
362
+
363
+ # TODO: Reconsider the following cases
364
+ [ 0, 0, 55, 233 ],
365
+ [ 0, 55, 0, 233 ],
366
+ [ 55, 0, 0, 233 ],
367
+ [ 0, 0, 74, 234 ],
368
+ [ 0, 74, 0, 234 ],
369
+ [ 74, 0, 0, 234 ],
370
+ ].each do |r, g, b, code|
371
+ label = "rgb(#{r}, #{g}, #{b}) is color #{code}"
372
+ data_set[label] = [code, Colors::RGB.new(r, g, b)]
373
+ end
374
+ data_set
375
+ end
376
+ def test_to_xterm256
377
+ code, rgb = data
378
+ assert_equal(Colors::Xterm256.new(code),
379
+ rgb.to_xterm256)
380
+ end
321
381
  end
@@ -0,0 +1,76 @@
1
+ class ColorsXterm256Test < Test::Unit::TestCase
2
+ include TestHelper
3
+
4
+ sub_test_case(".new") do
5
+ sub_test_case("with color code") do
6
+ test("the regular case") do
7
+ codes = [16, 255]
8
+ colors = codes.map {|i| Colors::Xterm256.new(i) }
9
+ assert_equal(codes,
10
+ colors.map(&:code))
11
+ end
12
+
13
+ data do
14
+ (0..15).map { |code|
15
+ ["ANSI color #{code}", code]
16
+ }.to_h
17
+ end
18
+ def test_ansi_color_code(code)
19
+ assert_raise(ArgumentError) do
20
+ Colors::Xterm256.new(code)
21
+ end
22
+ end
23
+
24
+ test("the negative argument") do
25
+ assert_raise(ArgumentError) do
26
+ Colors::Xterm256.new(-1)
27
+ end
28
+ end
29
+
30
+ test("too large argument") do
31
+ assert_raise(ArgumentError) do
32
+ Colors::Xterm256.new(256)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ test("==") do
39
+ assert { Colors::Xterm256.new(16) == Colors::Xterm256.new(16) }
40
+ assert { Colors::Xterm256.new(132) == Colors::Xterm256.new(132) }
41
+ end
42
+
43
+ test("!=") do
44
+ assert { Colors::Xterm256.new(16) != Colors::Xterm256.new(17) }
45
+ end
46
+
47
+ data do
48
+ data_set = {}
49
+ # colors 16-231 are a 6x6x6 color cube
50
+ (0...6).each do |r|
51
+ (0...6).each do |g|
52
+ (0...6).each do |b|
53
+ code = 6*(6*r + g) + b + 16
54
+ red = (r > 0) ? 40*r + 55 : r
55
+ green = (g > 0) ? 40*g + 55 : g
56
+ blue = (b > 0) ? 40*b + 55 : b
57
+ label = "Color #{code} is rgb(#{red}, #{green}, #{blue})"
58
+ data_set[label] = [code, Colors::RGB.new(red, green, blue)]
59
+ end
60
+ end
61
+ end
62
+ # colors 232-256 are grayscale colors
63
+ (0...24).each do |y|
64
+ code = 232 + y
65
+ level = 10*y + 8
66
+ label = "Color #{code} is gray(#{level})"
67
+ data_set[label] = [code, Colors::RGB.new(level, level, level)]
68
+ end
69
+ data_set
70
+ end
71
+ def test_to_rgb(data)
72
+ code, rgb = data
73
+ assert_equal(rgb,
74
+ Colors::Xterm256.new(code).to_rgb)
75
+ end
76
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: red-colors
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenta Murata
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-19 00:00:00.000000000 Z
11
+ date: 2021-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -105,6 +105,7 @@ files:
105
105
  - lib/colors/rgb.rb
106
106
  - lib/colors/rgba.rb
107
107
  - lib/colors/version.rb
108
+ - lib/colors/xterm256.rb
108
109
  - lib/colors/xyy.rb
109
110
  - lib/colors/xyz.rb
110
111
  - red-colors.gemspec
@@ -116,6 +117,7 @@ files:
116
117
  - test/test-named-color.rb
117
118
  - test/test-rgb.rb
118
119
  - test/test-rgba.rb
120
+ - test/test-xterm256.rb
119
121
  - test/test-xyz.rb
120
122
  homepage: https://github.com/red-data-tools/red-colors
121
123
  licenses:
@@ -136,19 +138,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
138
  - !ruby/object:Gem::Version
137
139
  version: '0'
138
140
  requirements: []
139
- rubyforge_project:
140
- rubygems_version: 2.7.6.2
141
+ rubygems_version: 3.2.3
141
142
  signing_key:
142
143
  specification_version: 4
143
144
  summary: Red Colors provides a wide array of features for dealing with colors. This
144
145
  includes conversion between colorspaces, desaturation, and parsing colors.
145
146
  test_files:
146
- - test/test-hsla.rb
147
- - test/test-named-color.rb
148
- - test/test-rgba.rb
149
147
  - test/helper.rb
150
- - test/test-rgb.rb
151
148
  - test/run.rb
152
149
  - test/test-hsl.rb
153
- - test/test-xyz.rb
150
+ - test/test-hsla.rb
154
151
  - test/test-husl.rb
152
+ - test/test-named-color.rb
153
+ - test/test-rgb.rb
154
+ - test/test-rgba.rb
155
+ - test/test-xterm256.rb
156
+ - test/test-xyz.rb