red-colors 0.1.1 → 0.1.2

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.
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