color 2.0.0 → 2.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee63ea78d61f49aac704bb5dad67aece3ec38392032742dd0feb97b26ef22362
4
- data.tar.gz: a72e49de5357ab7826e52cdc6b2df8afd814c0f1b680e526b66ef17de80d445d
3
+ metadata.gz: 40ce91bfc8f772f3a22829e81620a7ed6b5cbc0c17b2b779c2680811df98adfb
4
+ data.tar.gz: c694153e0f54a6b310df3412379e2b57beaf393b72a70e659d6ce5b4489ab9e2
5
5
  SHA512:
6
- metadata.gz: 64afd6ed2802840e688bedb460fc530e72471bef5ae96833902348c6309b2d553e52c3e1538e621c347814f4fc349edf61bfead93a1bcfac789163f8906d9aa4
7
- data.tar.gz: ad710aa1a92a1061b46dc04dd182e8253aa24f8f4959ef2bbd86be89def51ad9d90a15fcdf264b75f9c4268091350b571659520346a65a054c37d42914482aa7
6
+ metadata.gz: f6276623790aed0ec56a46e3e86cd00e76d5579bb8d71044f3d58532af59c834c55ce15202ff2a64514a817810236b01f1fe22484a54ea9ee093e0f997312323
7
+ data.tar.gz: 3207d0833c0a85159e77816b71d9c312c5d78f40c5f5fe00022d615ecbe19f24fd06bcbfbce9562085a925473544d2ced2e4ce472ee8d456f5d310f9ff6261db
data/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.1.0 / 2025-07-20
4
+
5
+ Color 2.1.0 fixes a computation bug where CIE XYZ values were improperly clamped
6
+ and adds more Color::XYZ white points for standard illuminants.
7
+
8
+ - Fixes a bug where standard illuminant white points were improperly clamped and
9
+ was seen in `Color::RGB#to_lab` since CIELAB conversions must go through the
10
+ XYZ color model. Even though we were using the D65 white point, the Z value
11
+ was being clamped to 1.0 instead of the correct value of ≅1.08. Reported by
12
+ @r-plus in [#45][issue-45] and fixed in [#45][pr-46].
13
+
14
+ The resulting Color::LAB values are not _exactly_ the same values under Color
15
+ 1.8, but they are within fractional differences deemed acceptable.
16
+
17
+ - Added more white points for standard illuminants in the Color::XYZ::WP2
18
+ constant. The values here were derived from the
19
+ [White points of standard illuminants][wp-std-illuminant] using the `xyY` to
20
+ `XYZ` conversion formula where `X = (x * Y) / y` and
21
+ `Z = ((1 - x - y) * Y) / y`. Only the values for CIE 1931 2° were computed.
22
+ The values for Color::XYZ::D50 and Color::XYZ::D65 were replaced with these
23
+ computed values.
24
+
25
+ ## 2.0.1 / 2025-07-05
26
+
27
+ Color 2.0.1 is a minor documentation update.
28
+
3
29
  ## 2.0.0 / 2025-07-05
4
30
 
5
31
  Color 2.0.0 is a major release of the Color library.
@@ -305,6 +331,9 @@ ownership to contribute it to this project under the licence terms.
305
331
  [css-device-cmyk]: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/device-cmyk
306
332
  [issue-10]: https://github.com/halostatue/color/issues/10
307
333
  [issue-30]: https://github.com/halostatue/color/issues/30
334
+ [issue-45]: https://github.com/halostatue/color/issues/45
308
335
  [pr-11]: https://github.com/halostatue/color/pull/11
309
- [pr-8]: https://github.com/halostatue/color/pulls/8
310
336
  [pr-36]: https://github.com/halostatue/color/pull/36
337
+ [pr-46]: https://github.com/halostatue/pull/46
338
+ [pr-8]: https://github.com/halostatue/color/pulls/8
339
+ [wp-std-illuminant]: https://en.wikipedia.org/wiki/Standard_illuminant#White_points_of_standard_illuminants
data/CONTRIBUTORS.md CHANGED
@@ -7,5 +7,6 @@
7
7
  - Aaron Hill (CIE94 color matching)
8
8
  - Luke Bennellick
9
9
  - @stiff (CIELAB color support)
10
+ - @r-plus
10
11
  - Matthew Draper
11
12
  - Charles Nutter
data/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  Color is a Ruby library to provide RGB, CMYK, HSL, and other color space
14
14
  manipulation support to applications that require it. It provides optional named
15
- RGB colors that are commonly supported in HTML, # SVG, and X11 applications.
15
+ RGB colors that are commonly supported in HTML, SVG, and X11 applications.
16
16
 
17
17
  The Color library performs purely mathematical manipulation of the colors based
18
18
  on color theory without reference to device color profiles (such as sRGB or
@@ -22,9 +22,11 @@ reliably converted to relative color spaces (like RGB) without color profiles.
22
22
  When necessary for conversions, Color provides D65 and D50 reference white
23
23
  values in Color::XYZ.
24
24
 
25
- Color 2.0 is a major release, dropping support for all versions of Ruby prior to
26
- 3.2 as well as removing or renaming a number of features. The main breaking
27
- changes are:
25
+ Color 2.1 fixes a Color::XYZ bug where the values were improperly clamped and
26
+ adds more Color::XYZ white points for standard illuminants. It builds on the
27
+ Color 2.0 major release, dropping support for all versions of Ruby prior to 3.2
28
+ as well as removing or renaming a number of features. The main breaking changes
29
+ are:
28
30
 
29
31
  - Color classes are immutable Data objects; they are no longer mutable.
30
32
  - RGB named colors are no longer loaded on gem startup, but must be required
@@ -33,7 +35,7 @@ changes are:
33
35
  - Color palettes have been removed.
34
36
  - `Color::CSS` and `Color::CSS#[]` have been removed.
35
37
 
36
- ## Examples
38
+ ## Example
37
39
 
38
40
  Suppose you want to make a given RGB color a little lighter. Adjusting the RGB
39
41
  color curves will change the hue and saturation will also change. Instead, use
data/lib/color/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Color
4
- VERSION = "2.0.0" # :nodoc:
4
+ VERSION = "2.1.0" # :nodoc:
5
5
  end
data/lib/color/xyz.rb CHANGED
@@ -83,15 +83,18 @@ class Color::XYZ
83
83
  # 0 and 1 and `x` and `z` must be fractional valiues greater than or equal to 0.
84
84
  #
85
85
  # ```ruby
86
- # Color::XYZ.from_fraction(0.95047, 1.0, 1.0.883)
86
+ # Color::XYZ.from_fraction(0.95047, 1.0, 1.0883)
87
87
  # Color::XYZ.new(0.95047, 1.0, 1.08883)
88
88
  # Color::XYZ[x: 0.95047, y: 1.0, z: 1.08883]
89
89
  # ```
90
90
  def initialize(x:, y:, z:)
91
+ # The X and Z values in the XYZ color model are technically unbounded. With Y scaled
92
+ # to 1.0, we will clamp X to 0.0..2.2 and Z to 0.0..2.8.
93
+
91
94
  super(
92
- x: normalize(x, 0.0..1.0),
95
+ x: normalize(x, 0.0..2.2),
93
96
  y: normalize(y),
94
- z: normalize(z, 0.0..1.0)
97
+ z: normalize(z, 0.0..2.8)
95
98
  )
96
99
  end
97
100
 
@@ -105,11 +108,70 @@ class Color::XYZ
105
108
  K = 24389r/27r # :nodoc:
106
109
  EK = E * K # :nodoc:
107
110
 
108
- # The D65 standard illuminant white point
109
- D65 = new(0.95047, 1.0, 1.08883)
111
+ ##
112
+ # White points for standard illuminants at 2° (CIE 1931).
113
+ WP2 = {
114
+ A: new(1.09849161234507, 1.0, 0.355798257454902),
115
+ B: new(0.9909274480248, 1.0, 0.853132732288615),
116
+ C: new(0.980705971659919, 1.0, 1.18224949392713),
117
+ D50: new(0.964211994421199, 1.0, 0.825188284518828),
118
+ D55: new(0.956797052643698, 1.0, 0.921480586017327),
119
+ D65: new(0.950430051970945, 1.0, 1.08880649180926),
120
+ D75: new(0.949722089884072, 1.0, 1.22639352072415),
121
+ D93: new(0.953014035205816, 1.0, 1.41274275520851),
122
+ E: new(1, 1.0, 1.0000300003),
123
+ F1: new(0.92833634773327, 1.0, 1.03664719660806),
124
+ F2: new(0.991446614618029, 1.0, 0.673159423379253),
125
+ F3: new(1.03753487192493, 1.0, 0.49860512300279),
126
+ F4: new(1.0914726375561, 1.0, 0.388132609288601),
127
+ F5: new(0.908719701138108, 1.0, 0.987228866815325),
128
+ F6: new(0.973091283635895, 1.0, 0.601905497618128),
129
+ F7: new(0.950171560440895, 1.0, 1.08629642000425),
130
+ F8: new(0.96412543554007, 1.0, 0.823331010452962),
131
+ F9: new(1.00364797081623, 1.0, 0.678683511708377),
132
+ F10: new(0.961735119213027, 1.0, 0.817123325737787),
133
+ F11: new(1.00898894280487, 1.0, 0.642616604353936),
134
+ F12: new(1.08046289656537, 1.0, 0.392275166291635),
135
+ "FL3.0": new(1.09273493677163, 1.0, 0.3868088271758),
136
+ "FL3.1": new(1.01981788966256, 1.0, 0.658275307980718),
137
+ "FL3.2": new(0.916836289619075, 1.0, 0.990985751671998),
138
+ "FL3.3": new(1.09547365817462, 1.0, 0.377937175364828),
139
+ "FL3.4": new(1.02096949891068, 1.0, 0.702342047930283),
140
+ "FL3.5": new(0.968888888888889, 1.0, 0.808888888888889),
141
+ "FL3.6": new(1.08380716934487, 1.0, 0.388380716934487),
142
+ "FL3.7": new(0.996868475991649, 1.0, 0.612734864300626),
143
+ "FL3.8": new(0.974380395433027, 1.0, 0.810359231411863),
144
+ "FL3.9": new(0.970505617977528, 1.0, 0.838483146067416),
145
+ "FL3.10": new(0.944962143273151, 1.0, 0.967093768200349),
146
+ "FL3.11": new(1.08422095615556, 1.0, 0.392865989596235),
147
+ "FL3.12": new(1.02846401718582, 1.0, 0.656820622986037),
148
+ "FL3.13": new(0.955112219451372, 1.0, 0.815738431698531),
149
+ "FL3.14": new(0.951034063260341, 1.0, 1.09032846715328),
150
+ HP1: new(1.28433734939759, 1.0, 0.125301204819277),
151
+ HP2: new(1.14911014911015, 1.0, 0.255892255892256),
152
+ HP3: new(1.05570552147239, 1.0, 0.398282208588957),
153
+ HP4: new(1.00395048722676, 1.0, 0.62970766394522),
154
+ HP5: new(1.01696741179639, 1.0, 0.676272555884729),
155
+ "LED-B1": new(1.11819519372241, 1.0, 0.3339872486513),
156
+ "LED-B2": new(1.08599202392822, 1.0, 0.406530408773679),
157
+ "LED-B3": new(1.0088638195004, 1.0, 0.677142089712597),
158
+ "LED-B4": new(0.977155910908053, 1.0, 0.87835522558538),
159
+ "LED-B5": new(0.963535228677379, 1.0, 1.12669962917182),
160
+ "LED-BH1": new(1.10034431874078, 1.0, 0.359075258239056),
161
+ "LED-RGB1": new(1.08216575635241, 1.0, 0.292567086202802),
162
+ "LED-V1": new(1.12462908011869, 1.0, 0.348170128585559),
163
+ "LED-V2": new(1.00158940397351, 1.0, 0.647417218543046),
164
+ ID50: new(0.952803997779012, 1.0, 0.823431426985008),
165
+ ID65: new(0.939522225582099, 1.0, 1.08436649531297)
166
+ }.freeze
110
167
 
111
- # The D50 standard illuminant white point
112
- D50 = new(0.96421, 1.0, 0.82521)
168
+ ##
169
+ # The D50 standard illuminant white point at 2° (CIE 1931).
170
+ D50 = WP2[:D50]
171
+
172
+ ##
173
+ # The D65 standard illuminant white point at 2° (CIE 1931).
174
+ D65 = WP2[:D65]
113
175
 
114
176
  ##
115
177
  # Coerces the other Color object into \XYZ.
data/lib/color.rb CHANGED
@@ -7,29 +7,27 @@
7
7
  # - **changelog**: [CHANGELOG](rdoc-ref:CHANGELOG.md)
8
8
  #
9
9
  # \Color is a Ruby library to provide RGB, CMYK, HSL, and other color space manipulation
10
- # support to applications that require it. It provides 152 named RGB colors that are
10
+ # support to applications that require it. It provides optional named RGB colors that are
11
11
  # commonly supported in HTML, SVG, and X11 applications.
12
12
  #
13
13
  # The \Color library performs purely mathematical manipulation of the colors based on
14
14
  # color theory without reference to device color profiles (such as sRGB or Adobe RGB). For
15
15
  # most purposes, when working with RGB and HSL color spaces, this won't matter. Absolute
16
- # color spaces (like CIE LAB and CIE XYZ), however, cannot be reliably converted to
17
- # relative color spaces (like RGB) without color profiles. When necessary for conversions,
18
- # \Color provides \D65 and \D50 reference white values in Color::XYZ.
16
+ # color spaces (like CIE LAB and CIE XYZ) cannot be reliably converted to relative color
17
+ # spaces (like RGB) without color profiles. When necessary for conversions, \Color
18
+ # provides \D65 and \D50 reference white values in Color::XYZ.
19
19
  #
20
- # \Color 2.0 is a major release to the \Color library, dropping support for all versions of
21
- # Ruby prior to 3.2.
20
+ # Color 2.1 fixes a Color::XYZ bug where the values were improperly clamped and adds more
21
+ # Color::XYZ white points for standard illuminants. It builds on the Color 2.0 major
22
+ # release, dropping support for all versions of Ruby prior to 3.2 as well as removing or
23
+ # renaming a number of features. The main breaking changes are:
22
24
  #
23
- # > **NOTE**: This is a pre-release version of \Color 2.0.
24
- # > The main goals for a 2.0 release have been met: modernizing the codebase, but
25
- # > consideration will be given to improving color transformation robustness and accuracy
26
- # > with Matrix operations and Rational numbers instead of floating point decimal values.
27
- #
28
- # In \Color 2.0, color objects are immutable (derived from Data) and do not expose the
29
- # `new` class method, instead using only `from_*` class methods. There is always
30
- # a `from_values` class method which represents the native color channel values (which may
31
- # not match the internal representation). This method _may_ have a counterpart that is
32
- # recommended for readability.
25
+ # - Color classes are immutable Data objects; they are no longer mutable.
26
+ # - RGB named colors are no longer loaded on gem startup, but must be required explicitly
27
+ # (this is _not_ done via `autoload` because there are more than 100 named colors with
28
+ # spelling variations) with `require "color/rgb/colors"`.
29
+ # - Color palettes have been removed.
30
+ # - `Color::CSS` and `Color::CSS#[]` have been removed.
33
31
  module Color
34
32
  ##
35
33
  # The maximum "resolution" for color math; if any value is less than or equal to this
data/test/test_rgb.rb CHANGED
@@ -317,6 +317,15 @@ module TestColor
317
317
  end
318
318
  end
319
319
 
320
+ def test_fix_45_invalid_rgb_to_lab
321
+ assert_equal(
322
+ Color::CIELAB[56.2562, 88.1033, -18.8203],
323
+ Color::RGB.by_hex("#ff00aa").to_lab
324
+ )
325
+
326
+ assert_equal("#ff00aa", Color::RGB.by_hex("#ff00aa").to_lab.to_rgb.html)
327
+ end
328
+
320
329
  # # An RGB color round-tripped through CIELAB should still have more or less the same
321
330
  # # RGB values, but this doesn't really work because the color math here is slightly
322
331
  # # wrong.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: color
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Austin Ziegler
@@ -213,7 +213,7 @@ dependencies:
213
213
  description: |-
214
214
  Color is a Ruby library to provide RGB, CMYK, HSL, and other color space
215
215
  manipulation support to applications that require it. It provides optional named
216
- RGB colors that are commonly supported in HTML, # SVG, and X11 applications.
216
+ RGB colors that are commonly supported in HTML, SVG, and X11 applications.
217
217
 
218
218
  The Color library performs purely mathematical manipulation of the colors based
219
219
  on color theory without reference to device color profiles (such as sRGB or
@@ -223,9 +223,11 @@ description: |-
223
223
  When necessary for conversions, Color provides D65 and D50 reference white
224
224
  values in Color::XYZ.
225
225
 
226
- Color 2.0 is a major release, dropping support for all versions of Ruby prior to
227
- 3.2 as well as removing or renaming a number of features. The main breaking
228
- changes are:
226
+ Color 2.1 fixes a Color::XYZ bug where the values were improperly clamped and
227
+ adds more Color::XYZ white points for standard illuminants. It builds on the
228
+ Color 2.0 major release, dropping support for all versions of Ruby prior to 3.2
229
+ as well as removing or renaming a number of features. The main breaking changes
230
+ are:
229
231
 
230
232
  - Color classes are immutable Data objects; they are no longer mutable.
231
233
  - RGB named colors are no longer loaded on gem startup, but must be required