Nux

Merge lp:~unity-team/nux/nux.color-class into lp:nux/2.0

Proposed by Jay Taoko
Status: Merged
Approved by: Jay Taoko
Approved revision: 562
Merged at revision: 562
Proposed branch: lp:~unity-team/nux/nux.color-class
Merge into: lp:nux/2.0
Diff against target: 1339 lines (+683/-396)
9 files modified
Nux/ColorEditor.cpp (+18/-4)
NuxCore/Color.cpp (+290/-311)
NuxCore/Color.h (+108/-79)
NuxCore/Colors.cpp (+12/-0)
NuxCore/Colors.h (+7/-0)
NuxImage/ImageSurface.h (+1/-1)
configure.ac (+1/-1)
tests/Makefile.am (+1/-0)
tests/gtest-nuxcore-color.cpp (+245/-0)
To merge this branch: bzr merge lp:~unity-team/nux/nux.color-class
Reviewer Review Type Date Requested Status
Jay Taoko (community) Approve
Tim Penhey (community) Needs Fixing
Review via email: mp+91714@code.launchpad.net

Description of the change

* nux::Color is now a class rather than a struct
* Added support for pre-multiplied color
* Added tests for Color class
* Cleanup obsolete function calls

To post a comment you must log in.
lp:~unity-team/nux/nux.color-class updated
557. By Gord Allott

Adds very basic completion support to nux,
Essentially just adds text to the end of the TextEntry widget without any real logic as the logic we want for unity is
different from what we want for a toolkit

Basically just a visual change to allow hud to offer completion. Fixes: . Approved by Tim Penhey.

558. By Thomi Richards

Moved keycode definitions from unity into nux, where they belong.. Fixes: . Approved by Jay Taoko.

559. By Jason Smith

Improves dash startup times dramatically.. Fixes: . Approved by Thomi Richards.

Revision history for this message
Tim Penhey (thumper) wrote :

If you are changing the copyright, use
  2010-2012
to extend the date not replace.

I don't think that SetPremultiplied should take any params.

void Color::Premultiply()
{
  if (premultiplied_) return;

  red *= alpha;
  blue *= alpha;
  green *= alpha;
  premultiplied_ = true;
}

Then inside GetPremultiplied, then use:

  Color c(*this);
  c.Premultiply();
  return c;

Should the assignment operator also check operator ==?

What about the operators, do they care?

Re: tests,

perhaps we should have some conversion functions tested for well known HSV, RGB, and HLS values.

review: Needs Fixing
Revision history for this message
Jay Taoko (jaytaoko) wrote :

> If you are changing the copyright, use
> 2010-2012
> to extend the date not replace.
>
> I don't think that SetPremultiplied should take any params.
>

Why? GetPremultiply do not take parameters. I don't see the issue with SetPremultiply. You don't have to use it; it is there if you need it.

> void Color::Premultiply()
> {
> if (premultiplied_) return;
>
> red *= alpha;
> blue *= alpha;
> green *= alpha;
> premultiplied_ = true;
> }
>
> Then inside GetPremultiplied, then use:
>
> Color c(*this);
> c.Premultiply();
> return c;
>
> Should the assignment operator also check operator ==?

The implicit assignment operator and copy constructor will work fine.
Yes, operator == has been fixed.

> What about the operators, do they care?

Other operators are left to perform as usual.

> Re: tests,
>
> perhaps we should have some conversion functions tested for well known HSV,
> RGB, and HLS values.

I have taken random reference values from generally accepted tools such as Photoshop and used Nux's internal conversion routines to match them closely. It is enough to start. More can be added later.

lp:~unity-team/nux/nux.color-class updated
560. By Jason Smith

Makes nux lazy load some of its less frequently use, yet more expensive objects. Fixes: . Approved by Jay Taoko, Thomi Richards.

561. By Jay Taoko

* Expose the StaticText device texture
* Code style fixes. Fixes: . Approved by Jason Smith.

Revision history for this message
Jay Taoko (jaytaoko) :
review: Approve
lp:~unity-team/nux/nux.color-class updated
562. By Jay Taoko

* Merged with Nux trunk
* Updated ABI version

Revision history for this message
Jay Taoko (jaytaoko) :
review: Needs Fixing
Revision history for this message
Jay Taoko (jaytaoko) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Nux/ColorEditor.cpp'
2--- Nux/ColorEditor.cpp 2011-12-29 18:06:53 +0000
3+++ Nux/ColorEditor.cpp 2012-02-10 04:48:18 +0000
4@@ -504,7 +504,10 @@
5 Geometry basepickermarker = Geometry(channel_area_->GetBaseX(), channel_area_->GetBaseY() + m_VertMarkerPosition.y, 5, 5);
6
7 Color color(rgb_.red, rgb_.green, rgb_.blue);
8- GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, OneMinusLuminance(rgb_));
9+ float luma = color::LumaRed * rgb_.red + color::LumaGreen * rgb_.green + color::LumaBlue * rgb_.blue;
10+ Color one_minus_luma(1.0f - luma, 1.0f - luma, 1.0f - luma);
11+
12+ GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, one_minus_luma);
13
14 GetPainter().Paint2DQuadColor(graphics_engine, channel_area_->GetGeometry(), BaseChannelTop, BaseChannelBottom, BaseChannelBottom, BaseChannelTop);
15 // Draw Marker on Base Chanel Area
16@@ -556,7 +559,10 @@
17 GetPainter().Paint2DQuadVGradient(graphics_engine, p, Color(1.0f * v, 1.0f * v, s * v), Color(1.0f * v, s * v, s * v));
18
19 Geometry pickermarker = Geometry(GetBaseX() + m_MarkerPosition.x - 2, GetBaseY() + m_MarkerPosition.y - 2, 5, 5);
20- GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, OneMinusLuminance(rgb_));
21+
22+ float luma = color::LumaRed * rgb_.red + color::LumaGreen * rgb_.green + color::LumaBlue * rgb_.blue;
23+ Color one_minus_luma(1.0f - luma, 1.0f - luma, 1.0f - luma);
24+ GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, one_minus_luma);
25 }
26 else if (color_channel_ == color::SATURATION)
27 {
28@@ -578,7 +584,11 @@
29
30 //Geometry pickermarker = Geometry(GetX() + x - 2, GetY() + y -2, 5, 5);
31 Geometry pickermarker = Geometry(GetBaseX() + m_MarkerPosition.x - 2, GetBaseY() + m_MarkerPosition.y - 2, 5, 5);
32- GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, OneMinusLuminance(rgb_));
33+
34+ float luma = color::LumaRed * rgb_.red + color::LumaGreen * rgb_.green + color::LumaBlue * rgb_.blue;
35+ Color one_minus_luma(1.0f - luma, 1.0f - luma, 1.0f - luma);
36+
37+ GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, one_minus_luma);
38 GetPainter().Paint2DQuadColor(graphics_engine, channel_area_->GetGeometry(), BaseChannelTop, BaseChannelBottom, BaseChannelBottom, BaseChannelTop);
39 }
40 else if (color_channel_ == color::VALUE)
41@@ -598,7 +608,11 @@
42
43 //Geometry pickermarker = Geometry(GetX() + x - 2, GetY() + y -2, 5, 5);
44 Geometry pickermarker = Geometry(GetBaseX() + m_MarkerPosition.x - 2, GetBaseY() + m_MarkerPosition.y - 2, 5, 5);
45- GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, OneMinusLuminance(rgb_));
46+
47+ float luma = color::LumaRed * rgb_.red + color::LumaGreen * rgb_.green + color::LumaBlue * rgb_.blue;
48+ Color one_minus_luma(1.0f - luma, 1.0f - luma, 1.0f - luma);
49+
50+ GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, one_minus_luma);
51 GetPainter().Paint2DQuadColor(graphics_engine, channel_area_->GetGeometry(), BaseChannelTop, BaseChannelBottom, BaseChannelBottom, BaseChannelTop);
52 }
53
54
55=== modified file 'NuxCore/Color.cpp'
56--- NuxCore/Color.cpp 2011-10-21 22:06:35 +0000
57+++ NuxCore/Color.cpp 2012-02-10 04:48:18 +0000
58@@ -1,5 +1,5 @@
59 /*
60- * Copyright 2010 Inalogic® Inc.
61+ * Copyright 2010-2012 Inalogic® Inc.
62 *
63 * This program is free software: you can redistribute it and/or modify it
64 * under the terms of the GNU Lesser General Public License, as
65@@ -35,186 +35,188 @@
66 {
67 namespace color
68 {
69-
70 Color::Color()
71- : red(0)
72- , green(0)
73- , blue(0)
74- , alpha(1)
75- {
76- }
77+ : red(0.0f)
78+ , green(0.0f)
79+ , blue(0.0f)
80+ , alpha(1.0f)
81+ , premultiplied_(false)
82+ {}
83
84-Color::Color(RedGreenBlue const& rgb, float a)
85- : red(rgb.red)
86- , green(rgb.green)
87- , blue(rgb.blue)
88- , alpha(a)
89-{}
90+ Color::Color(RedGreenBlue const& rgb, float a)
91+ : red(rgb.red)
92+ , green(rgb.green)
93+ , blue(rgb.blue)
94+ , alpha(a)
95+ , premultiplied_(false)
96+ {}
97
98 Color::Color (unsigned int c)
99- : red(NUX_RGBA_GET_RED(c) / 255.f)
100- , green(NUX_RGBA_GET_GREEN(c) / 255.f)
101- , blue(NUX_RGBA_GET_BLUE(c) / 255.f)
102- , alpha(NUX_RGBA_GET_ALPHA(c) / 255.f)
103- {
104- }
105+ : red(NUX_RGBA_GET_RED(c) / 255.0f)
106+ , green(NUX_RGBA_GET_GREEN(c) / 255.0f)
107+ , blue(NUX_RGBA_GET_BLUE(c) / 255.0f)
108+ , alpha(NUX_RGBA_GET_ALPHA(c) / 255.0f)
109+ , premultiplied_(false)
110+ {}
111
112 Color::Color(int r, int g, int b)
113- : red(r / 255.f)
114- , green(g / 255.f)
115- , blue(b / 255.f)
116- , alpha(1)
117- {
118- }
119-
120- Color::Color (float r, float g, float b, float a)
121- : red(r)
122- , green(g)
123- , blue(b)
124- , alpha(a)
125- {
126- }
127-
128-bool operator == (const Color &lhs, const Color &rhs)
129-{
130- return (lhs.red == rhs.red &&
131- lhs.green == rhs.green &&
132- lhs.blue == rhs.blue &&
133- lhs.alpha == rhs.alpha);
134-}
135-
136-bool operator != (const Color &lhs, const Color &rhs)
137-{
138- return !(lhs == rhs);
139-}
140-
141-Color ClampVal(Color const& c)
142-{
143- return Color(std::max(0.0f, std::min(1.0f, c.red)),
144- std::max(0.0f, std::min(1.0f, c.green)),
145- std::max(0.0f, std::min(1.0f, c.blue)),
146- std::max(0.0f, std::min(1.0f, c.alpha)));
147-}
148-
149-Color Luminance(Color const& c)
150-{
151- float L = 0.30f * c.red + 0.59f * c.green + 0.11f * c.blue;
152- return Color(L, L, L);
153-}
154-
155-Color OneMinusLuminance(Color const& c)
156-{
157- float L = 1.0f - (0.30f * c.red + 0.59f * c.green + 0.11f * c.blue);
158- return Color(L, L, L);
159-}
160-
161-Color RandomColor()
162-{
163- return Color(RandomColorINT());
164-}
165-
166-Color MakeOpaque(Color const& c)
167-{
168- return Color(c.red, c.green, c.blue, 1.0f);
169-}
170-
171-unsigned int RandomColorINT()
172-{
173- // std::rand isn't defined to be more random than 2^15, so we need
174- // to generate the full unsigned in chunks.
175- return (((std::rand() % 255) << 24) |
176- ((std::rand() % 255) << 16) |
177- ((std::rand() % 255) << 8) |
178- (std::rand() % 255));
179-}
180-
181-Color operator + (Color const& lhs, Color const& rhs)
182-{
183- return Color(lhs.red + rhs.red,
184- lhs.green + rhs.green,
185- lhs.blue + rhs.blue,
186- lhs.alpha + rhs.alpha);
187-}
188-
189-Color operator - (Color const& lhs, Color const& rhs)
190-{
191- return Color(lhs.red - rhs.red,
192- lhs.green - rhs.green,
193- lhs.blue - rhs.blue,
194- lhs.alpha - rhs.alpha);
195-}
196-
197-Color operator + (float scalar, Color const& c)
198-{
199- return Color(c.red + scalar,
200- c.green + scalar,
201- c.blue + scalar,
202- c.alpha + scalar);
203-}
204-
205-Color operator + (Color const& c, float scalar)
206-{
207- return scalar + c;
208-}
209-
210-Color operator - (float scalar, Color const& c)
211-{
212- return Color(scalar - c.red,
213- scalar - c.green,
214- scalar - c.blue,
215- scalar - c.alpha);
216-}
217-
218-
219-Color operator - (Color const& c, float scalar)
220-{
221- return Color(c.red - scalar,
222- c.green - scalar,
223- c.blue - scalar,
224- c.alpha - scalar);
225-}
226-
227-Color operator * (float scalar, Color const& c)
228-{
229- return Color(c.red * scalar,
230- c.green * scalar,
231- c.blue * scalar,
232- c.alpha * scalar);
233-}
234-
235-Color operator * (Color const& c, float scalar)
236-{
237- return scalar * c;
238-}
239-
240-// The Hue/Saturation/Value model was created by A. R. Smith in 1978. It is
241-// based on such intuitive color characteristics as tint, shade and tone (or
242-// family, purety and intensity). The coordinate system is cylindrical, and
243-// the colors are defined inside a hexcone. The hue value H runs from 0 to
244-// 360º. The saturation S is the degree of strength or purity and is from 0 to
245-// 1. Purity is how much white is added to the color, so S=1 makes the purest
246-// color (no white). Brightness V also ranges from 0 to 1, where 0 is the
247-// black. There is no transformation matrix for RGB/HSV conversion, but the
248-// algorithm follows:
249-
250-// r,g,b values are from 0 to 1
251-// h = [0,360], s = [0,1], v = [0,1]
252-// if s == 0, then h = -1 (undefined)
253-
254- void RGBtoHSV ( float r, float g, float b, float &h, float &s, float &v )
255+ : red(r / 255.0f)
256+ , green(g / 255.0f)
257+ , blue(b / 255.0f)
258+ , alpha(1.0f)
259+ , premultiplied_(false)
260+ {}
261+
262+ Color::Color(float r, float g, float b, float a)
263+ : red(r)
264+ , green(g)
265+ , blue(b)
266+ , alpha(a)
267+ , premultiplied_(false)
268+ {}
269+
270+ Color Color::GetPremultiplied()
271+ {
272+ if (premultiplied_)
273+ {
274+ // Already pre-multiplied. Return *this;
275+ return *this;
276+ }
277+
278+ Color c;
279+ c.SetPremultiplied(red, green, blue, alpha);
280+ return c;
281+ }
282+
283+ void Color::SetPremultiplied(float r, float g, float b, float a)
284+ {
285+ red = r * a;
286+ green = g * a;
287+ blue = b * a;
288+ alpha = a;
289+ premultiplied_ = true;
290+ }
291+
292+ bool Color::IsPremultiplied()
293+ {
294+ return premultiplied_;
295+ }
296+
297+ bool operator == (const Color& lhs, const Color& rhs)
298+ {
299+ return (lhs.red == rhs.red &&
300+ lhs.green == rhs.green &&
301+ lhs.blue == rhs.blue &&
302+ lhs.alpha == rhs.alpha &&
303+ lhs.premultiplied_ == rhs.premultiplied_);
304+ }
305+
306+ bool operator != (const Color& lhs, const Color& rhs)
307+ {
308+ return !(lhs == rhs);
309+ }
310+
311+ Color RandomColor()
312+ {
313+ return Color(RandomColorINT());
314+ }
315+
316+ unsigned int RandomColorINT()
317+ {
318+ // std::rand isn't defined to be more random than 2^15, so we need
319+ // to generate the full unsigned in chunks.
320+ return (((std::rand() % 255) << 24) |
321+ ((std::rand() % 255) << 16) |
322+ ((std::rand() % 255) << 8) |
323+ (std::rand() % 255));
324+ }
325+
326+ Color operator + (Color const& lhs, Color const& rhs)
327+ {
328+ return Color(lhs.red + rhs.red,
329+ lhs.green + rhs.green,
330+ lhs.blue + rhs.blue,
331+ lhs.alpha + rhs.alpha);
332+ }
333+
334+ Color operator - (Color const& lhs, Color const& rhs)
335+ {
336+ return Color(lhs.red - rhs.red,
337+ lhs.green - rhs.green,
338+ lhs.blue - rhs.blue,
339+ lhs.alpha - rhs.alpha);
340+ }
341+
342+ Color operator + (float scalar, Color const& c)
343+ {
344+ return Color(c.red + scalar,
345+ c.green + scalar,
346+ c.blue + scalar,
347+ c.alpha + scalar);
348+ }
349+
350+ Color operator + (Color const& c, float scalar)
351+ {
352+ return scalar + c;
353+ }
354+
355+ Color operator - (float scalar, Color const& c)
356+ {
357+ return Color(scalar - c.red,
358+ scalar - c.green,
359+ scalar - c.blue,
360+ scalar - c.alpha);
361+ }
362+
363+
364+ Color operator - (Color const& c, float scalar)
365+ {
366+ return Color(c.red - scalar,
367+ c.green - scalar,
368+ c.blue - scalar,
369+ c.alpha - scalar);
370+ }
371+
372+ Color operator * (float scalar, Color const& c)
373+ {
374+ return Color(c.red * scalar,
375+ c.green * scalar,
376+ c.blue * scalar,
377+ c.alpha * scalar);
378+ }
379+
380+ Color operator * (Color const& c, float scalar)
381+ {
382+ return scalar * c;
383+ }
384+
385+ // The Hue/Saturation/Value model was created by A. R. Smith in 1978. It is
386+ // based on such intuitive color characteristics as tint, shade and tone (or
387+ // family, purety and intensity). The coordinate system is cylindrical, and
388+ // the colors are defined inside a hexcone. The hue value H runs from 0 to
389+ // 360º. The saturation S is the degree of strength or purity and is from 0 to
390+ // 1. Purity is how much white is added to the color, so S=1 makes the purest
391+ // color (no white). Brightness V also ranges from 0 to 1, where 0 is the
392+ // black. There is no transformation matrix for RGB/HSV conversion, but the
393+ // algorithm follows:
394+
395+ // r,g,b values are from 0 to 1
396+ // h = [0,360], s = [0,1], v = [0,1]
397+ // if s == 0, then h = -1 (undefined)
398+ void RGBtoHSV(float r, float g, float b, float& h, float& s, float& v)
399 {
400 float mini, maxi, delta;
401
402 mini = std::min(std::min(r, g), b);
403 maxi = std::max(std::max(r, g), b);
404- v = maxi; // v
405+ v = maxi;
406
407 delta = maxi - mini;
408
409
410- if ( maxi != 0 )
411+ if (maxi != 0)
412 {
413- s = delta / maxi; // s
414+ s = delta / maxi;
415 }
416 else
417 {
418@@ -231,24 +233,24 @@
419 return;
420 }
421
422- if ( r == maxi)
423- h = ( g - b ) / delta; // between yellow & magenta
424- else if ( g == maxi)
425- h = 2 + ( b - r ) / delta; // between cyan & yellow
426+ if (r == maxi)
427+ h = (g - b) / delta; // between yellow & magenta
428+ else if (g == maxi)
429+ h = 2 + (b - r) / delta; // between cyan & yellow
430 else
431- h = 4 + ( r - g ) / delta; // between magenta & cyan
432+ h = 4 + (r - g) / delta; // between magenta & cyan
433
434 h *= 60; // degrees
435
436- if ( h < 0 )
437+ if (h < 0)
438 h += 360;
439
440 // convert h from [0, 360] to [0, 1]
441- h = (h) / 360.0f;
442+ h = h / 360.0f;
443
444 }
445
446- void HSVtoRGB ( float &r, float &g, float &b, float h, float s, float v )
447+ void HSVtoRGB(float& r, float& g, float& b, float h, float s, float v )
448 {
449 int i;
450 float f, p, q, t;
451@@ -256,19 +258,19 @@
452 // convert h from [0, 1] to [0, 360]
453 h = h * 360.0f;
454
455- if ( s == 0 )
456+ if (s == 0)
457 {
458 // achromatic (grey)
459 r = g = b = v;
460 return;
461 }
462
463- h /= 60; // sector 0 to 5
464- i = (int) std::floor ( h );
465- f = h - i; // factorial part of h
466- p = v * ( 1 - s );
467- q = v * ( 1 - s * f );
468- t = v * ( 1 - s * ( 1 - f ) );
469+ h /= 60.0f; // sector 0 to 5
470+ i = (int) std::floor(h);
471+ f = h - i; // factorial part of h
472+ p = v * (1 - s);
473+ q = v * (1 - s * f);
474+ t = v * (1 - s * (1 - f));
475
476 switch ( i )
477 {
478@@ -297,7 +299,7 @@
479 g = p;
480 b = v;
481 break;
482- default: // case 5:
483+ default: // case 5:
484 r = v;
485 g = p;
486 b = q;
487@@ -305,30 +307,34 @@
488 }
489 }
490
491-/////////////////////////
492-// HLS-RGB Conversions //
493-/////////////////////////
494+ /////////////////////////
495+ // HLS-RGB Conversions //
496+ /////////////////////////
497
498- float HLStoRGB1 (float rn1, float rn2, float huei)
499+ // Static function. Auxiliary to HLS2RGB().
500+ static float HLStoRGB_(float rn1, float rn2, float huei)
501 {
502- // Static method. Auxiliary to HLS2RGB().
503-
504 float hue = huei;
505
506- if (hue > 360) hue = hue - 360;
507-
508- if (hue < 0) hue = hue + 360;
509-
510- if (hue < 60 ) return rn1 + (rn2 - rn1) * hue / 60;
511-
512- if (hue < 180) return rn2;
513-
514- if (hue < 240) return rn1 + (rn2 - rn1) * (240 - hue) / 60;
515+ if (hue > 360.0f)
516+ hue = hue - 360.0f;
517+
518+ if (hue < 0.0f)
519+ hue = hue + 360.0f;
520+
521+ if (hue < 60.0f )
522+ return rn1 + (rn2 - rn1) * hue / 60.0f;
523+
524+ if (hue < 180.0f)
525+ return rn2;
526+
527+ if (hue < 240.0f)
528+ return rn1 + (rn2 - rn1) * (240.0f - hue) / 60.0f;
529
530 return rn1;
531 }
532
533- void HLStoRGB (float &r, float &g, float &b, float hue, float light, float satur)
534+ void HLStoRGB(float& r, float& g, float& b, float hue, float light, float satur)
535 {
536 // Static method to compute RGB from HLS. The l and s are between [0,1]
537 // and h is between [0, 1]. The returned r,g,b triplet is between [0,1].
538@@ -337,17 +343,23 @@
539 float rh, rl, rs, rm1, rm2;
540 rh = rl = rs = 0;
541
542- if (hue > 0) rh = hue;
543-
544- if (rh > 360) rh = 360;
545-
546- if (light > 0) rl = light;
547-
548- if (rl > 1) rl = 1;
549-
550- if (satur > 0) rs = satur;
551-
552- if (rs > 1) rs = 1;
553+ if (hue > 0)
554+ rh = hue;
555+
556+ if (rh > 360.0f)
557+ rh = 360.0f;
558+
559+ if (light > 0)
560+ rl = light;
561+
562+ if (rl > 1)
563+ rl = 1;
564+
565+ if (satur > 0)
566+ rs = satur;
567+
568+ if (rs > 1)
569+ rs = 1.0f;
570
571 if (rl <= 0.5f)
572 rm2 = rl * (1.0f + rs);
573@@ -364,34 +376,13 @@
574 return;
575 }
576
577- r = HLStoRGB1 (rm1, rm2, rh + 120);
578- g = HLStoRGB1 (rm1, rm2, rh);
579- b = HLStoRGB1 (rm1, rm2, rh - 120);
580- }
581-
582- void HLStoRGBi (int h, int l, int s, int &r, int &g, int &b)
583- {
584- // Static method to compute RGB from HLS. The h,l,s are between [0,255].
585- // The returned r,g,b triplet is between [0,255].
586-
587- float hh, ll, ss;
588- float rr, gg, bb;
589- hh = ll = ss = 0;
590- rr = gg = bb = 0;
591-
592- hh = float (h) * 360 / 255;
593- ll = float (l) / 255;
594- ss = float (s) / 255;
595-
596- HLStoRGB (hh, ll, ss, rr, gg, bb);
597-
598- r = (int) (rr * 255);
599- g = (int) (gg * 255);
600- b = (int) (bb * 255);
601- }
602-
603- void RGBtoHLS (float rr, float gg, float bb,
604- float &hue, float &light, float &satur)
605+ r = HLStoRGB_(rm1, rm2, rh + 120);
606+ g = HLStoRGB_(rm1, rm2, rh);
607+ b = HLStoRGB_(rm1, rm2, rh - 120);
608+ }
609+
610+ void RGBtoHLS(float rr, float gg, float bb,
611+ float& hue, float& light, float& satur)
612 {
613 // Static method to compute HLS from RGB. The r,g,b triplet is between
614 // [0,1], hue is between [0,1], light and satur are [0,1].
615@@ -399,29 +390,39 @@
616 float rnorm, gnorm, bnorm, minval, maxval, msum, mdiff, r, g, b;
617 r = g = b = 0;
618
619- if (rr > 0) r = rr;
620-
621- if (r > 1) r = 1;
622-
623- if (gg > 0) g = gg;
624-
625- if (g > 1) g = 1;
626-
627- if (bb > 0) b = bb;
628-
629- if (b > 1) b = 1;
630+ if (rr > 0)
631+ r = rr;
632+
633+ if (r > 1)
634+ r = 1;
635+
636+ if (gg > 0)
637+ g = gg;
638+
639+ if (g > 1)
640+ g = 1;
641+
642+ if (bb > 0)
643+ b = bb;
644+
645+ if (b > 1)
646+ b = 1;
647
648 minval = r;
649
650- if (g < minval) minval = g;
651+ if (g < minval)
652+ minval = g;
653
654- if (b < minval) minval = b;
655+ if (b < minval)
656+ minval = b;
657
658 maxval = r;
659
660- if (g > maxval) maxval = g;
661+ if (g > maxval)
662+ maxval = g;
663
664- if (b > maxval) maxval = b;
665+ if (b > maxval)
666+ maxval = b;
667
668 rnorm = gnorm = bnorm = 0;
669 mdiff = maxval - minval;
670@@ -458,74 +459,52 @@
671 hue = hue / 360.0f;
672 }
673
674-
675- void RGBtoHLSi (int r, int g, int b, int &h, int &l, int &s)
676- {
677- // Static method to compute HLS from RGB. The r,g,b triplet is between
678- // [0,255], hue, light and satur are between [0,255].
679-
680- float rr, gg, bb, hue, light, satur;
681-
682- rr = float (r) / 255;
683- gg = float (g) / 255;
684- bb = float (b) / 255;
685-
686- RGBtoHLS (rr, gg, bb, hue, light, satur);
687-
688- h = (int) (hue / 360 * 255);
689- l = (int) (light * 255);
690- s = (int) (satur * 255);
691- }
692-
693-
694-RedGreenBlue::RedGreenBlue(float r, float g, float b)
695+ RedGreenBlue::RedGreenBlue(float r, float g, float b)
696 : red(r)
697 , green(g)
698 , blue(b)
699-{}
700-
701-RedGreenBlue::RedGreenBlue(HueSaturationValue const& hsv)
702-{
703- HSVtoRGB(red, green, blue, hsv.hue, hsv.saturation, hsv.value);
704-}
705-
706-RedGreenBlue::RedGreenBlue(HueLightnessSaturation const& hls)
707-{
708- HLStoRGB(red, green, blue, hls.hue, hls.lightness, hls.saturation);
709-}
710-
711-HueSaturationValue::HueSaturationValue(float h, float s, float v)
712+ {}
713+
714+ RedGreenBlue::RedGreenBlue(HueSaturationValue const& hsv)
715+ {
716+ HSVtoRGB(red, green, blue, hsv.hue, hsv.saturation, hsv.value);
717+ }
718+
719+ RedGreenBlue::RedGreenBlue(HueLightnessSaturation const& hls)
720+ {
721+ HLStoRGB(red, green, blue, hls.hue, hls.lightness, hls.saturation);
722+ }
723+
724+ HueSaturationValue::HueSaturationValue(float h, float s, float v)
725 : hue(h)
726 , saturation(s)
727 , value(v)
728-{}
729-
730-HueSaturationValue::HueSaturationValue(RedGreenBlue const& rgb)
731-{
732- RGBtoHSV(rgb.red, rgb.green, rgb.blue, hue, saturation, value);
733-}
734-
735-HueSaturationValue::HueSaturationValue(Color const& c)
736-{
737- RGBtoHSV(c.red, c.green, c.blue, hue, saturation, value);
738-}
739-
740-HueLightnessSaturation::HueLightnessSaturation(float h, float l, float s)
741+ {}
742+
743+ HueSaturationValue::HueSaturationValue(RedGreenBlue const& rgb)
744+ {
745+ RGBtoHSV(rgb.red, rgb.green, rgb.blue, hue, saturation, value);
746+ }
747+
748+ HueSaturationValue::HueSaturationValue(Color const& c)
749+ {
750+ RGBtoHSV(c.red, c.green, c.blue, hue, saturation, value);
751+ }
752+
753+ HueLightnessSaturation::HueLightnessSaturation(float h, float l, float s)
754 : hue(h)
755 , lightness(l)
756 , saturation(s)
757-{}
758-
759-HueLightnessSaturation::HueLightnessSaturation(RedGreenBlue const& rgb)
760-{
761- RGBtoHLS(rgb.red, rgb.green, rgb.blue, hue, lightness, saturation);
762-}
763-
764-HueLightnessSaturation::HueLightnessSaturation(Color const& c)
765-{
766- RGBtoHLS(c.red, c.green, c.blue, hue, lightness, saturation);
767-}
768-
769-
770+ {}
771+
772+ HueLightnessSaturation::HueLightnessSaturation(RedGreenBlue const& rgb)
773+ {
774+ RGBtoHLS(rgb.red, rgb.green, rgb.blue, hue, lightness, saturation);
775+ }
776+
777+ HueLightnessSaturation::HueLightnessSaturation(Color const& c)
778+ {
779+ RGBtoHLS(c.red, c.green, c.blue, hue, lightness, saturation);
780+ }
781 }
782 }
783
784=== modified file 'NuxCore/Color.h'
785--- NuxCore/Color.h 2011-05-26 21:08:18 +0000
786+++ NuxCore/Color.h 2012-02-10 04:48:18 +0000
787@@ -1,5 +1,5 @@
788 /*
789- * Copyright 2010 Inalogic® Inc.
790+ * Copyright 2010-2012 Inalogic® Inc.
791 *
792 * This program is free software: you can redistribute it and/or modify it
793 * under the terms of the GNU Lesser General Public License, as
794@@ -81,14 +81,16 @@
795 //| blue | green | red | alpha |
796 //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
797
798-enum Model {
799+ enum Model
800+ {
801 RGB,
802 HSV,
803 HLS,
804 YUV
805-};
806+ };
807
808-enum Channel {
809+ enum Channel
810+ {
811 RED,
812 GREEN,
813 BLUE,
814@@ -96,94 +98,121 @@
815 SATURATION,
816 LIGHT,
817 VALUE
818-};
819+ };
820
821-enum Format {
822+ enum Format
823+ {
824 FLOAT,
825 HEX,
826 INT
827-};
828-
829-struct RedGreenBlue;
830-
831-struct Color
832-{
833+ };
834+
835+ class RedGreenBlue;
836+
837+ class Color
838+ {
839+ public:
840 Color();
841- explicit Color (unsigned int c);
842+ explicit Color(unsigned int c);
843 Color(int r, int g, int b);
844 Color(float r, float g, float b, float a = 1.0f);
845 Color(RedGreenBlue const& rgb, float a = 1.0f);
846+
847+ //! Returns the pre-multiplied version of this color.
848+ /*!
849+ Returns the pre-multiplied version of this color. If this color is already pre-multiplied
850+ then *this is returned.\n
851+ The premultiplied color is Color(red * alpha, green * alpha, blue * alpha, alpha).
852+
853+ @return The pre-multiplied version of this color.
854+ */
855+ Color GetPremultiplied();
856+
857+ //! Sets a pre-multiplied color
858+ /*!
859+ Sets a pre-multiplied color
860+
861+ @param r Red value.
862+ @param g Green value.
863+ @param b Blue value.
864+ @param a Alpha value.
865+ */
866+ void SetPremultiplied(float r, float g, float b, float a);
867+
868+ //! Returns True if this color is pre-multiplied.
869+ /*!
870+ Returns True if this color is pre-multiplied.
871+
872+ @return True is this color is pre-multiplied.
873+ */
874+ bool IsPremultiplied();
875
876 float red;
877 float green;
878 float blue;
879 float alpha;
880-};
881-
882-bool operator == (Color const& lhs, Color const& rhs);
883-bool operator != (Color const& lhs, Color const& rhs);
884-
885-Color ClampVal(Color const&);
886-Color Saturate(Color const&);
887-Color Complement(Color const&);
888-Color Luminance(Color const&);
889-Color OneMinusLuminance(Color const&);
890-Color MakeOpaque(Color const&);
891-
892-Color operator + (Color const&, Color const&);
893-Color operator + (float, Color const&);
894-Color operator + (Color const&, float);
895-
896-Color operator - (Color const&, Color const&);
897-Color operator - (float, Color const&);
898-Color operator - (Color const&, float);
899-
900-Color operator * (float, Color const&);
901-Color operator * (Color const&, float);
902-
903-Color RandomColor();
904-unsigned int RandomColorINT();
905-
906-struct HueSaturationValue;
907-struct HueLightnessSaturation;
908-
909-struct RedGreenBlue
910-{
911- RedGreenBlue(float r, float g, float b);
912- RedGreenBlue(HueSaturationValue const&);
913- RedGreenBlue(HueLightnessSaturation const&);
914-
915- float red;
916- float green;
917- float blue;
918-};
919-
920-struct HueSaturationValue
921-{
922- HueSaturationValue(float h, float s, float v);
923- HueSaturationValue(Color const&);
924- HueSaturationValue(RedGreenBlue const&);
925-
926- float hue;
927- float saturation;
928- float value;
929-};
930-
931-struct HueLightnessSaturation
932-{
933- HueLightnessSaturation(float h, float l, float s);
934- HueLightnessSaturation(Color const&);
935- HueLightnessSaturation(RedGreenBlue const&);
936-
937- float hue;
938- float lightness;
939- float saturation;
940-};
941-
942-// void RGBtoHSV ( float r, float g, float b, float &h, float &s, float &v );
943-// void HSVtoRGB ( float &r, float &g, float &b, float h, float s, float v );
944-// void HLStoRGB (float &r, float &g, float &b, float hue, float light, float satur);
945-// void RGBtoHLS (float rr, float gg, float bb, float &hue, float &light, float &satur);
946+
947+ protected:
948+ bool premultiplied_; //!< True if the rgb components have been pre-multiplied with the alpha component.
949+
950+ friend bool operator == (Color const& lhs, Color const& rhs);
951+ };
952+
953+ bool operator == (Color const& lhs, Color const& rhs);
954+ bool operator != (Color const& lhs, Color const& rhs);
955+
956+ Color operator + (Color const&, Color const&);
957+ Color operator + (float, Color const&);
958+ Color operator + (Color const&, float);
959+
960+ Color operator - (Color const&, Color const&);
961+ Color operator - (float, Color const&);
962+ Color operator - (Color const&, float);
963+
964+ Color operator * (float, Color const&);
965+ Color operator * (Color const&, float);
966+
967+ Color RandomColor();
968+ unsigned int RandomColorINT();
969+
970+ class HueSaturationValue;
971+ class HueLightnessSaturation;
972+
973+ class RedGreenBlue
974+ {
975+ public:
976+ RedGreenBlue(float r, float g, float b);
977+ RedGreenBlue(HueSaturationValue const&);
978+ RedGreenBlue(HueLightnessSaturation const&);
979+
980+ float red;
981+ float green;
982+ float blue;
983+ };
984+
985+ class HueSaturationValue
986+ {
987+ public:
988+ HueSaturationValue(float h, float s, float v);
989+ HueSaturationValue(Color const&);
990+ HueSaturationValue(RedGreenBlue const&);
991+
992+ float hue;
993+ float saturation;
994+ float value;
995+ };
996+
997+ class HueLightnessSaturation
998+ {
999+ public:
1000+ HueLightnessSaturation(float h, float l, float s);
1001+ HueLightnessSaturation(Color const&);
1002+ HueLightnessSaturation(RedGreenBlue const&);
1003+
1004+ float hue;
1005+ float lightness;
1006+ float saturation;
1007+ };
1008
1009 }
1010 using color::Color;
1011
1012=== modified file 'NuxCore/Colors.cpp'
1013--- NuxCore/Colors.cpp 2011-05-13 03:20:36 +0000
1014+++ NuxCore/Colors.cpp 2012-02-10 04:48:18 +0000
1015@@ -26,6 +26,18 @@
1016 {
1017 namespace color
1018 {
1019+ // Definition of Luma coefficients as per ITU-R Recommendation BT.601
1020+ // http://en.wikipedia.org/wiki/Rec._601
1021+ const float LumaRed = 0.299f;
1022+ const float LumaGreen = 0.587f;
1023+ const float LumaBlue = 0.114f;
1024+
1025+ // // Definition of Luma coefficients as per ITU-R Recommendation BT.709
1026+ // // http://en.wikipedia.org/wiki/Rec._709
1027+ // float LumaRed = 0.2126f;
1028+ // float LumaGreen = 0.7152f;
1029+ // float LumaBlue = 0.0722f;
1030+
1031 const Color Transparent(0, 0, 0, 0);
1032
1033 //Red colors
1034
1035=== modified file 'NuxCore/Colors.h'
1036--- NuxCore/Colors.h 2011-05-13 03:20:36 +0000
1037+++ NuxCore/Colors.h 2012-02-10 04:48:18 +0000
1038@@ -28,6 +28,13 @@
1039 {
1040 namespace color
1041 {
1042+ // Definition of Luma coefficients as per ITU-R Recommendation BT.709
1043+ // http://en.wikipedia.org/wiki/Rec._709
1044+
1045+ extern const float LumaRed;
1046+ extern const float LumaGreen;
1047+ extern const float LumaBlue;
1048+
1049 // X11 color names from:http://en.wikipedia.org/wiki/Web_colors
1050 extern const Color Transparent;
1051
1052
1053=== modified file 'NuxImage/ImageSurface.h'
1054--- NuxImage/ImageSurface.h 2012-01-22 04:31:33 +0000
1055+++ NuxImage/ImageSurface.h 2012-02-10 04:48:18 +0000
1056@@ -149,7 +149,7 @@
1057 Sum up all the image elements and divide by the number of elements.
1058 @return The average color of the image.
1059 */
1060- struct Color AverageColor();
1061+ Color AverageColor();
1062
1063 private:
1064 void FlipDXTVertical();
1065
1066=== modified file 'configure.ac'
1067--- configure.ac 2012-02-09 20:32:08 +0000
1068+++ configure.ac 2012-02-10 04:48:18 +0000
1069@@ -22,7 +22,7 @@
1070 # The number format is : year/month/day
1071 # e.g.: december 5th, 2011 is: 20111205
1072 # To make more than one API change in a day, add a number to the date. Like 20111205.xx
1073-m4_define([nux_abi_version], [20120209.01])
1074+m4_define([nux_abi_version], [20120209.02])
1075
1076 m4_define([nux_version],
1077 [nux_major_version.nux_minor_version.nux_micro_version])
1078
1079=== modified file 'tests/Makefile.am'
1080--- tests/Makefile.am 2012-01-30 08:43:49 +0000
1081+++ tests/Makefile.am 2012-02-10 04:48:18 +0000
1082@@ -45,6 +45,7 @@
1083 gtest_nux_core_SOURCES = \
1084 Helpers.h \
1085 Helpers.cpp \
1086+ gtest-nuxcore-color.cpp \
1087 test_object.cpp \
1088 test_main.cpp \
1089 test_async_file_writer.cpp \
1090
1091=== added file 'tests/gtest-nuxcore-color.cpp'
1092--- tests/gtest-nuxcore-color.cpp 1970-01-01 00:00:00 +0000
1093+++ tests/gtest-nuxcore-color.cpp 2012-02-10 04:48:18 +0000
1094@@ -0,0 +1,245 @@
1095+/*
1096+ * Copyright 2012 Inalogic Inc.
1097+ *
1098+ * This program is free software: you can redistribute it and/or modify it
1099+ * under the terms of the GNU Lesser General Public License version 3, as
1100+ * published by the Free Software Foundation.
1101+ *
1102+ * This program is distributed in the hope that it will be useful, but
1103+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1104+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
1105+ * PURPOSE. See the applicable version of the GNU Lesser General Public
1106+ * License for more details.
1107+ *
1108+ * You should have received a copy of both the GNU Lesser General Public
1109+ * License version 3 along with this program. If not, see
1110+ * <http://www.gnu.org/licenses/>
1111+ *
1112+ * Authored by: Jay Taoko <jaytaoko@inalogic.com>
1113+ *
1114+ */
1115+
1116+#include <gmock/gmock.h>
1117+
1118+#include "Nux/Nux.h"
1119+
1120+using namespace testing;
1121+
1122+static const float epsilon = 0.005f;
1123+
1124+namespace {
1125+
1126+ TEST(TestColor, TestColorConstructor0)
1127+ {
1128+ nux::Color c;
1129+
1130+ EXPECT_EQ(c.red, 0.0f);
1131+ EXPECT_EQ(c.green, 0.0f);
1132+ EXPECT_EQ(c.blue, 0.0f);
1133+ EXPECT_EQ(c.alpha, 1.0);
1134+ EXPECT_EQ(c.IsPremultiplied(), false);
1135+ }
1136+
1137+ TEST(TestColor, TestColorConstructor1)
1138+ {
1139+ // testing float inputs
1140+ nux::Color c0(0.1f, 0.2f, 0.3f);
1141+ EXPECT_EQ(c0.red, 0.1f);
1142+ EXPECT_EQ(c0.green, 0.2f);
1143+ EXPECT_EQ(c0.blue, 0.3f);
1144+ EXPECT_EQ(c0.alpha, 1.0f);
1145+ EXPECT_EQ(c0.IsPremultiplied(), false);
1146+
1147+ // testing float inputs
1148+ nux::Color c1(0.1f, 0.2f, 0.3f, 0.4f);
1149+ EXPECT_EQ(c1.red, 0.1f);
1150+ EXPECT_EQ(c1.green, 0.2f);
1151+ EXPECT_EQ(c1.blue, 0.3f);
1152+ EXPECT_EQ(c1.alpha, 0.4f);
1153+ EXPECT_EQ(c1.IsPremultiplied(), false);
1154+
1155+ // testing double inputs
1156+ nux::Color c2(0.1, 0.2, 0.3, 0.4);
1157+ EXPECT_EQ(c2.red, 0.1f);
1158+ EXPECT_EQ(c2.green, 0.2f);
1159+ EXPECT_EQ(c2.blue, 0.3f);
1160+ EXPECT_EQ(c2.alpha, 0.4f);
1161+ EXPECT_EQ(c2.IsPremultiplied(), false);
1162+ }
1163+
1164+ TEST(TestColor, TestColorConstructor2)
1165+ {
1166+ nux::Color c0(255, 255, 255);
1167+ EXPECT_EQ(c0.red, 1.0f);
1168+ EXPECT_EQ(c0.green, 1.0f);
1169+ EXPECT_EQ(c0.blue, 1.0f);
1170+ EXPECT_EQ(c0.alpha, 1.0f);
1171+ EXPECT_EQ(c0.IsPremultiplied(), false);
1172+
1173+ nux::Color c1(10, 128, 192);
1174+ EXPECT_EQ(c1.red, 10/255.0f);
1175+ EXPECT_EQ(c1.green, 128/255.0f);
1176+ EXPECT_EQ(c1.blue, 192/255.0f);
1177+ EXPECT_EQ(c1.alpha, 1.0f);
1178+ EXPECT_EQ(c1.IsPremultiplied(), false);
1179+ }
1180+
1181+ TEST(TestColor, TestColorConstructor3)
1182+ {
1183+ nux::Color c0((255<<24)|(255<<16)|(255<<8)|255);
1184+ EXPECT_EQ(c0.red, 1.0f);
1185+ EXPECT_EQ(c0.green, 1.0f);
1186+ EXPECT_EQ(c0.blue, 1.0f);
1187+ EXPECT_EQ(c0.alpha, 1.0f);
1188+ EXPECT_EQ(c0.IsPremultiplied(), false);
1189+
1190+ // A R G B
1191+ nux::Color c1((128<<24)|(192<<16)|(128<<8)|10);
1192+ EXPECT_EQ(c1.red, 192/255.0f);
1193+ EXPECT_EQ(c1.green, 128/255.0f);
1194+ EXPECT_EQ(c1.blue, 10/255.0f);
1195+ EXPECT_EQ(c1.alpha, 128/255.0f);
1196+ EXPECT_EQ(c1.IsPremultiplied(), false);
1197+ }
1198+
1199+
1200+ TEST(TestColor, TestColorPremultiplied0)
1201+ {
1202+ nux::Color c0(0.81f, 0.24f, 0.53f, 0.79f);
1203+ EXPECT_EQ(c0.red, 0.81f);
1204+ EXPECT_EQ(c0.green, 0.24f);
1205+ EXPECT_EQ(c0.blue, 0.53f);
1206+ EXPECT_EQ(c0.alpha, 0.79f);
1207+ EXPECT_EQ(c0.IsPremultiplied(), false);
1208+
1209+ nux::Color c1 = c0.GetPremultiplied();
1210+ EXPECT_EQ(c1.red, 0.81f * 0.79f);
1211+ EXPECT_EQ(c1.green, 0.24f * 0.79f);
1212+ EXPECT_EQ(c1.blue, 0.53f * 0.79f);
1213+ EXPECT_EQ(c1.alpha, 0.79f);
1214+ EXPECT_EQ(c1.IsPremultiplied(), true);
1215+ EXPECT_EQ(c0.IsPremultiplied(), false);
1216+ }
1217+
1218+ TEST(TestColor, TestColorRGBToHSV0)
1219+ {
1220+ nux::color::RedGreenBlue rgb(255/255.0f, 128/255.0f, 169/255.0f);
1221+ nux::color::HueSaturationValue hsv(rgb);
1222+
1223+ EXPECT_NEAR(hsv.hue, 341/360.0f, epsilon);
1224+ EXPECT_NEAR(hsv.saturation, 50/100.0f, epsilon);
1225+ EXPECT_NEAR(hsv.value, 100/100.0f, epsilon);
1226+ }
1227+
1228+ TEST(TestColor, TestColorHSVToRGB0)
1229+ {
1230+ nux::color::HueSaturationValue hsv(341/360.0f, 50/100.0f, 100/100.0f);
1231+ nux::color::RedGreenBlue rgb(hsv);
1232+
1233+ EXPECT_NEAR(rgb.red, 255/255.0f, epsilon);
1234+ EXPECT_NEAR(rgb.green, 128/255.0f, epsilon);
1235+ EXPECT_NEAR(rgb.blue, 169/255.0f, epsilon);
1236+ }
1237+
1238+ TEST(TestColor, TestColorRGBToHSV1)
1239+ {
1240+ nux::color::RedGreenBlue rgb(65/255.0f, 28/255.0f, 6/255.0f);
1241+ nux::color::HueSaturationValue hsv(rgb);
1242+
1243+ EXPECT_NEAR(hsv.hue, 22/360.0f, epsilon);
1244+ EXPECT_NEAR(hsv.saturation, 91/100.0f, epsilon);
1245+ EXPECT_NEAR(hsv.value, 25/100.0f, epsilon);
1246+ }
1247+
1248+ TEST(TestColor, TestColorHSVToRGB1)
1249+ {
1250+ nux::color::HueSaturationValue hsv(22/360.0f, 91/100.0f, 25/100.0f);
1251+ nux::color::RedGreenBlue rgb(hsv);
1252+
1253+ EXPECT_NEAR(rgb.red, 65/255.0f, epsilon);
1254+ EXPECT_NEAR(rgb.green, 28/255.0f, epsilon);
1255+ EXPECT_NEAR(rgb.blue, 6/255.0f, epsilon);
1256+ }
1257+
1258+ TEST(TestColor, TestColorRGBToHSV2)
1259+ {
1260+ nux::color::RedGreenBlue rgb(90/255.0f, 65/255.0f, 158/255.0f);
1261+ nux::color::HueSaturationValue hsv(rgb);
1262+
1263+ EXPECT_NEAR(hsv.hue, 256/360.0f, epsilon);
1264+ EXPECT_NEAR(hsv.saturation, 59/100.0f, epsilon);
1265+ EXPECT_NEAR(hsv.value, 62/100.0f, epsilon);
1266+ }
1267+
1268+
1269+ TEST(TestColor, TestColorHSVToRGB2)
1270+ {
1271+ nux::color::HueSaturationValue hsv(256/360.0f, 59/100.0f, 62/100.0f);
1272+ nux::color::RedGreenBlue rgb(hsv);
1273+
1274+ EXPECT_NEAR(rgb.red, 90/255.0f, epsilon);
1275+ EXPECT_NEAR(rgb.green, 65/255.0f, epsilon);
1276+ EXPECT_NEAR(rgb.blue, 158/255.0f, epsilon);
1277+ }
1278+
1279+ TEST(TestColor, TestColorRGBToHLS0)
1280+ {
1281+ nux::color::RedGreenBlue rgb(127/255.0f, 0/255.0f, 255/255.0f);
1282+ nux::color::HueLightnessSaturation hls(rgb);
1283+
1284+ EXPECT_NEAR(hls.hue, 270/360.0f, epsilon);
1285+ EXPECT_NEAR(hls.lightness, 50/100.0f, epsilon);
1286+ EXPECT_NEAR(hls.saturation, 100/100.0f, epsilon);
1287+ }
1288+
1289+ TEST(TestColor, TestColorHLSToRGB0)
1290+ {
1291+ nux::color::HueLightnessSaturation hls(270/360.0f, 50/100.0f, 100/100.0f);
1292+ nux::color::RedGreenBlue rgb(hls);
1293+
1294+ EXPECT_NEAR(rgb.red, 127/255.0f, epsilon);
1295+ EXPECT_NEAR(rgb.green, 0/255.0f, epsilon);
1296+ EXPECT_NEAR(rgb.blue, 255/255.0f, epsilon);
1297+ }
1298+
1299+ TEST(TestColor, TestColorRGBToHLS1)
1300+ {
1301+ nux::color::RedGreenBlue rgb(50/255.0f, 84/255.0f, 13/255.0f);
1302+ nux::color::HueLightnessSaturation hls(rgb);
1303+
1304+ EXPECT_NEAR(hls.hue, 89/360.0f, epsilon);
1305+ EXPECT_NEAR(hls.lightness, 19/100.0f, epsilon);
1306+ EXPECT_NEAR(hls.saturation, 73/100.0f, epsilon);
1307+ }
1308+
1309+ TEST(TestColor, TestColorHLSToRGB1)
1310+ {
1311+ nux::color::HueLightnessSaturation hls(89/360.0f, 19/100.0f, 73/100.0f);
1312+ nux::color::RedGreenBlue rgb(hls);
1313+
1314+ EXPECT_NEAR(rgb.red, 50/255.0f, epsilon);
1315+ EXPECT_NEAR(rgb.green, 84/255.0f, epsilon);
1316+ EXPECT_NEAR(rgb.blue, 13/255.0f, epsilon);
1317+ }
1318+
1319+ TEST(TestColor, TestColorRGBToHLS2)
1320+ {
1321+ nux::color::RedGreenBlue rgb(201/255.0f, 200/255.0f, 239/255.0f);
1322+ nux::color::HueLightnessSaturation hls(rgb);
1323+
1324+ EXPECT_NEAR(hls.hue, 242/360.0f, epsilon);
1325+ EXPECT_NEAR(hls.lightness, 86/100.0f, epsilon);
1326+ EXPECT_NEAR(hls.saturation, 55/100.0f, epsilon);
1327+ }
1328+
1329+ TEST(TestColor, TestColorHLSToRGB2)
1330+ {
1331+ nux::color::HueLightnessSaturation hls(242/360.0f, 86/100.0f, 55/100.0f);
1332+ nux::color::RedGreenBlue rgb(hls);
1333+
1334+ EXPECT_NEAR(rgb.red, 201/255.0f, epsilon);
1335+ EXPECT_NEAR(rgb.green, 200/255.0f, epsilon);
1336+ EXPECT_NEAR(rgb.blue, 239/255.0f, epsilon);
1337+ }
1338+}
1339+

Subscribers

People subscribed via source and target branches

to all changes: