KiCad PCB EDA Suite
Loading...
Searching...
No Matches
color4d.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright 2012 Torsten Hueter, torstenhtr <at> gmx.de
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <map>
27#include <json_common.h>
28#include <gal/color4d.h>
29#include <i18n_utility.h>
30#include <wx/crt.h>
31#include <math/util.h>
32#include <core/kicad_algo.h>
33
34using namespace KIGFX;
35
36#define TS( string ) wxString( _HKI( string ) ).ToStdString()
37
38// We can't have this as a plain static variable, because it is referenced during the initialization
39// of other static variables, so we must initialize it explicitly on first use.
41{
42 static StructColors s_ColorRefs[NBCOLORS] =
43 {
44 { 0, 0, 0, BLACK, TS( "Black" ), DARKDARKGRAY },
45 { 72, 72, 72, DARKDARKGRAY, TS( "Gray 1" ), DARKGRAY },
46 { 132, 132, 132, DARKGRAY, TS( "Gray 2" ), LIGHTGRAY },
47 { 194, 194, 194, LIGHTGRAY, TS( "Gray 3" ), WHITE },
48 { 255, 255, 255, WHITE, TS( "White" ), WHITE },
49 { 194, 255, 255, LIGHTYELLOW, TS( "L.Yellow" ), WHITE },
50 { 191, 229, 255, LIGHTERORANGE, TS( "L.Orange" ), WHITE },
51 { 72, 0, 0, DARKBLUE, TS( "Blue 1" ), BLUE },
52 { 0, 72, 0, DARKGREEN, TS( "Green 1" ), GREEN },
53 { 72, 72, 0, DARKCYAN, TS( "Cyan 1" ), CYAN },
54 { 0, 0, 72, DARKRED, TS( "Red 1" ), RED },
55 { 72, 0, 72, DARKMAGENTA, TS( "Magenta 1" ), MAGENTA },
56 { 0, 72, 72, DARKBROWN, TS( "Brown 1" ), BROWN },
57 { 0, 77, 128, DARKORANGE, TS( "Orange 1" ), ORANGE },
58 { 132, 0, 0, BLUE, TS( "Blue 2" ), LIGHTBLUE },
59 { 0, 132, 0, GREEN, TS( "Green 2" ), LIGHTGREEN },
60 { 132, 132, 0, CYAN, TS( "Cyan 2" ), LIGHTCYAN },
61 { 0, 0, 132, RED, TS( "Red 2" ), LIGHTRED },
62 { 132, 0, 132, MAGENTA, TS( "Magenta 2" ), LIGHTMAGENTA },
63 { 0, 132, 132, BROWN, TS( "Brown 2" ), YELLOW },
64 { 0, 102, 204, ORANGE, TS( "Orange 2" ), LIGHTORANGE },
65 { 194, 0, 0, LIGHTBLUE, TS( "Blue 3" ), PUREBLUE, },
66 { 0, 194, 0, LIGHTGREEN, TS( "Green 3" ), PUREGREEN },
67 { 194, 194, 0, LIGHTCYAN, TS( "Cyan 3" ), PURECYAN },
68 { 0, 0, 194, LIGHTRED, TS( "Red 3" ), PURERED },
69 { 194, 0, 194, LIGHTMAGENTA, TS( "Magenta 3" ), PUREMAGENTA },
70 { 0, 194, 194, YELLOW, TS( "Yellow 3" ), PUREYELLOW },
71 { 0, 133, 221, LIGHTORANGE, TS( "Orange 3" ), PUREORANGE },
72 { 255, 0, 0, PUREBLUE, TS( "Blue 4" ), WHITE },
73 { 0, 255, 0, PUREGREEN, TS( "Green 4" ), WHITE },
74 { 255, 255, 0, PURECYAN, TS( "Cyan 4" ), WHITE },
75 { 0, 0, 255, PURERED, TS( "Red 4" ), WHITE },
76 { 255, 0, 255, PUREMAGENTA, TS( "Magenta 4" ), WHITE },
77 { 0, 255, 255, PUREYELLOW, TS( "Yellow 4" ), WHITE },
78 { 0, 153, 255, PUREORANGE, TS( "Orange 4" ), WHITE },
79 };
80 return s_ColorRefs;
81}
82
83
85{
86 if( aColor <= UNSPECIFIED_COLOR || aColor >= NBCOLORS )
87 {
89 return;
90 }
91
92 int candidate = 0;
93
94 for( ; candidate < NBCOLORS; ++candidate )
95 {
96 if( colorRefs()[candidate].m_Numcolor == aColor )
97 break;
98 }
99
100 if( candidate >= NBCOLORS )
101 {
102 *this = COLOR4D::UNSPECIFIED;
103 return;
104 }
105
106 r = colorRefs()[candidate].m_Red / 255.0;
107 g = colorRefs()[candidate].m_Green / 255.0;
108 b = colorRefs()[candidate].m_Blue / 255.0;
109 a = 1.0;
110 m_text = std::nullopt;
111}
112
113
114COLOR4D::COLOR4D( const wxString& aColorStr )
115{
116 if( !SetFromHexString( aColorStr ) && !SetFromWxString( aColorStr ) )
117 m_text = aColorStr;
118}
119
120
121COLOR4D::COLOR4D( const wxColour& aColor )
122{
123 r = aColor.Red() / 255.0;
124 g = aColor.Green() / 255.0;
125 b = aColor.Blue() / 255.0;
126 a = aColor.Alpha() / 255.0;
127 m_text = std::nullopt;
128}
129
130
131bool COLOR4D::SetFromWxString( const wxString& aColorString )
132{
133 wxColour c;
134
135 if( c.Set( aColorString ) )
136 {
137 r = c.Red() / 255.0;
138 g = c.Green() / 255.0;
139 b = c.Blue() / 255.0;
140 a = c.Alpha() / 255.0;
141 m_text = std::nullopt;
142
143 return true;
144 }
145
146 return false;
147}
148
149
150wxString COLOR4D::ToCSSString() const
151{
152 wxColour c = ToColour();
153 wxString str;
154
155 const int red = c.Red();
156 const int green = c.Green();
157 const int blue = c.Blue();
158 const int alpha = c.Alpha();
159
160 if ( alpha == wxALPHA_OPAQUE )
161 {
162 str.Printf( wxT( "rgb(%d, %d, %d)" ), red, green, blue );
163 }
164 else // use rgba() form
165 {
166 wxString alpha_str = wxString::FromCDouble( alpha / 255.0, 3 );
167
168 // The wxC2S_CSS_SYNTAX is particularly sensitive to ','s (as it uses them for value
169 // delimiters), and wxWidgets is known to be buggy in this respect when dealing with
170 // Serbian and Russian locales (at least), so we enforce an extra level of safety.
171 alpha_str.Replace( wxT( "," ), wxT( "." ) );
172
173 str.Printf( wxT( "rgba(%d, %d, %d, %s)" ), red, green, blue, alpha_str );
174 }
175
176 return str;
177}
178
179
180bool COLOR4D::SetFromHexString( const wxString& aColorString )
181{
182 wxString str = aColorString;
183 str.Trim( true );
184 str.Trim( false );
185
186 if( str.length() < 7 || !str.StartsWith( '#' ) )
187 return false;
188
189 unsigned long tmp;
190
191 if( wxSscanf( str.wx_str() + 1, wxT( "%lx" ), &tmp ) != 1 )
192 return false;
193
194 if( str.length() >= 9 )
195 {
196 r = ( (tmp >> 24) & 0xFF ) / 255.0;
197 g = ( (tmp >> 16) & 0xFF ) / 255.0;
198 b = ( (tmp >> 8) & 0xFF ) / 255.0;
199 a = ( tmp & 0xFF ) / 255.0;
200 }
201 else
202 {
203 r = ( (tmp >> 16) & 0xFF ) / 255.0;
204 g = ( (tmp >> 8) & 0xFF ) / 255.0;
205 b = ( tmp & 0xFF ) / 255.0;
206 a = 1.0;
207 }
208
209 m_text = std::nullopt;
210
211 return true;
212}
213
214
215wxString COLOR4D::ToHexString() const
216{
217 return wxString::Format( wxT("#%02X%02X%02X%02X" ),
218 KiROUND( r * 255.0 ),
219 KiROUND( g * 255.0 ),
220 KiROUND( b * 255.0 ),
221 KiROUND( a * 255.0 ) );
222}
223
224
225wxColour COLOR4D::ToColour() const
226{
227 using CHAN_T = wxColourBase::ChannelType;
228
229 const wxColour colour(
230 static_cast<CHAN_T>( r * 255 + 0.5 ), static_cast<CHAN_T>( g * 255 + 0.5 ),
231 static_cast<CHAN_T>( b * 255 + 0.5 ), static_cast<CHAN_T>( a * 255 + 0.5 ) );
232 return colour;
233}
234
235
236COLOR4D COLOR4D::LegacyMix( const COLOR4D& aColor ) const
237{
238 COLOR4D candidate;
239
240 // Blend the two colors (i.e. OR the RGB values)
241 candidate.r = ( (unsigned) ( 255.0 * r ) | (unsigned) ( 255.0 * aColor.r ) ) / 255.0,
242 candidate.g = ( (unsigned) ( 255.0 * g ) | (unsigned) ( 255.0 * aColor.g ) ) / 255.0,
243 candidate.b = ( (unsigned) ( 255.0 * b ) | (unsigned) ( 255.0 * aColor.b ) ) / 255.0,
244
245 // the alpha channel can be reinitialized but what is the best value?
246 candidate.a = ( aColor.a + a ) / 2;
247
248 return candidate;
249}
250
251
252namespace KIGFX {
253
254bool operator==( const COLOR4D& lhs, const COLOR4D& rhs )
255{
256 if( lhs.m_text.has_value() || rhs.m_text.has_value() )
257 return lhs.m_text.value_or( wxEmptyString ) == rhs.m_text.value_or( wxEmptyString );
258
259 return lhs.a == rhs.a && lhs.r == rhs.r && lhs.g == rhs.g && lhs.b == rhs.b;
260}
261
262
263bool operator!=( const COLOR4D& lhs, const COLOR4D& rhs )
264{
265 return !( lhs == rhs );
266}
267
268
269bool operator<( const COLOR4D& lhs, const COLOR4D& rhs )
270{
271 if( lhs.m_text.has_value() || rhs.m_text.has_value() )
272 return lhs.m_text.value_or( wxEmptyString ) < rhs.m_text.value_or( wxEmptyString );
273
274 if( lhs.r < rhs.r )
275 return true;
276 else if( lhs.g < rhs.g )
277 return true;
278 else if( lhs.b < rhs.b )
279 return true;
280 else if( lhs.a < rhs.a )
281 return true;
282
283 return false;
284}
285
286
287std::ostream &operator<<( std::ostream &aStream, COLOR4D const &aColor )
288{
289 if( aColor.m_text.has_value() )
290 return aStream << aColor.m_text.value();
291
292 return aStream << aColor.ToCSSString();
293}
294
295
296void to_json( nlohmann::json& aJson, const COLOR4D& aColor )
297{
298 if( aColor.m_text.has_value() )
299 aJson = nlohmann::json( aColor.m_text.value().ToStdString() );
300 else
301 aJson = nlohmann::json( aColor.ToCSSString().ToStdString() );
302}
303
304
305void from_json( const nlohmann::json& aJson, COLOR4D& aColor )
306{
307 aColor.SetFromWxString( aJson.get<std::string>() );
308}
309
310}
311
312
313void COLOR4D::ToHSL( double& aOutHue, double& aOutSaturation, double& aOutLightness ) const
314{
315 auto min = std::min( r, std::min( g, b ) );
316 auto max = std::max( r, std::max( g, b ) );
317 auto diff = max - min;
318
319 aOutLightness = ( max + min ) / 2.0;
320
321 if( aOutLightness >= 1.0 )
322 aOutSaturation = 0.0;
323 else
324 aOutSaturation = diff / ( 1.0 - std::abs( 2.0 * aOutLightness - 1.0 ) );
325
326 double hue;
327
328 if( diff <= 0.0 )
329 hue = 0.0;
330 else if( max == r )
331 hue = ( g - b ) / diff;
332 else if( max == g )
333 hue = ( b - r ) / diff + 2.0;
334 else
335 hue = ( r - g ) / diff + 4.0;
336
337 aOutHue = hue > 0.0 ? hue * 60.0 : hue * 60.0 + 360.0;
338
339 while( aOutHue < 0.0 )
340 aOutHue += 360.0;
341}
342
343
344void COLOR4D::FromHSL( double aInHue, double aInSaturation, double aInLightness )
345{
346 const auto P = ( 1.0 - std::abs( 2.0 * aInLightness - 1.0 ) ) * aInSaturation;
347 const auto scaled_hue = aInHue / 60.0;
348 const auto Q = P * ( 1.0 - std::abs( std::fmod( scaled_hue, 2.0 ) - 1.0 ) );
349
350 r = g = b = aInLightness - P / 2.0;
351
352 if (scaled_hue < 1.0)
353 {
354 r += P;
355 g += Q;
356 }
357 else if (scaled_hue < 2.0)
358 {
359 r += Q;
360 g += P;
361 }
362 else if (scaled_hue < 3.0)
363 {
364 g += P;
365 b += Q;
366 }
367 else if (scaled_hue < 4.0)
368 {
369 g += Q;
370 b += P;
371 }
372 else if (scaled_hue < 5.0)
373 {
374 r += Q;
375 b += P;
376 }
377 else
378 {
379 r += P;
380 b += Q;
381 }
382
383 m_text = std::nullopt;
384}
385
386
387void COLOR4D::ToHSV( double& aOutHue, double& aOutSaturation, double& aOutValue,
388 bool aAlwaysDefineHue ) const
389{
390 double min, max, delta;
391
392 min = r < g ? r : g;
393 min = min < b ? min : b;
394
395 max = r > g ? r : g;
396 max = max > b ? max : b;
397
398 aOutValue = max; // value
399 delta = max - min;
400
401 if( max > 0.0 )
402 {
403 aOutSaturation = ( delta / max );
404 }
405 else // for black color (r = g = b = 0 ) saturation is set to 0.
406 {
407 aOutSaturation = 0.0;
408 aOutHue = aAlwaysDefineHue ? 0.0 : NAN;
409 return;
410 }
411
412 /* Hue in degrees (0...360) is coded according to this table
413 * 0 or 360 : red
414 * 60 : yellow
415 * 120 : green
416 * 180 : cyan
417 * 240 : blue
418 * 300 : magenta
419 */
420 if( delta != 0.0 )
421 {
422 if( r >= max )
423 aOutHue = ( g - b ) / delta; // between yellow & magenta
424 else if( g >= max )
425 aOutHue = 2.0 + ( b - r ) / delta; // between cyan & yellow
426 else
427 aOutHue = 4.0 + ( r - g ) / delta; // between magenta & cyan
428
429 aOutHue *= 60.0; // degrees
430
431 if( aOutHue < 0.0 )
432 aOutHue += 360.0;
433 }
434 else // delta = 0 means r = g = b. hue is set to 0.0
435 {
436 aOutHue = aAlwaysDefineHue ? 0.0 : NAN;
437 }
438}
439
440
441void COLOR4D::FromHSV( double aInH, double aInS, double aInV )
442{
443 if( aInS <= 0.0 )
444 {
445 r = aInV;
446 g = aInV;
447 b = aInV;
448 return;
449 }
450
451 double hh = aInH;
452
453 while( hh >= 360.0 )
454 hh -= 360.0;
455
456 /* Hue in degrees (0...360) is coded according to this table
457 * 0 or 360 : red
458 * 60 : yellow
459 * 120 : green
460 * 180 : cyan
461 * 240 : blue
462 * 300 : magenta
463 */
464 hh /= 60.0;
465
466 int i = (int) hh;
467 double ff = hh - i;
468
469 double p = aInV * ( 1.0 - aInS );
470 double q = aInV * ( 1.0 - ( aInS * ff ) );
471 double t = aInV * ( 1.0 - ( aInS * ( 1.0 - ff ) ) );
472
473 switch( i )
474 {
475 case 0:
476 r = aInV;
477 g = t;
478 b = p;
479 break;
480
481 case 1:
482 r = q;
483 g = aInV;
484 b = p;
485 break;
486
487 case 2:
488 r = p;
489 g = aInV;
490 b = t;
491 break;
492
493 case 3:
494 r = p;
495 g = q;
496 b = aInV;
497 break;
498
499 case 4:
500 r = t;
501 g = p;
502 b = aInV;
503 break;
504
505 case 5:
506 default:
507 r = aInV;
508 g = p;
509 b = q;
510 break;
511 }
512
513 m_text = std::nullopt;
514}
515
516
517COLOR4D& COLOR4D::Saturate( double aFactor )
518{
519 // One can saturate a color only when r, v, b are not equal
520 if( r == g && r == b )
521 return *this;
522
523 double h, s, v;
524
525 ToHSV( h, s, v, true );
526 FromHSV( h, aFactor, 1.0 );
527
528 return *this;
529}
530
531
533{
534 // One can desaturate a color only when r, v, b are not equal
535 if( r == g && r == b )
536 return *this;
537
538 double h, s, l;
539
540 ToHSL( h, s, l );
541 FromHSL( h, 0.0, l );
542
543 return *this;
544}
545
546
547const COLOR4D COLOR4D::UNSPECIFIED( 0, 0, 0, 0 );
548const COLOR4D COLOR4D::WHITE( 1, 1, 1, 1 );
549const COLOR4D COLOR4D::BLACK( 0, 0, 0, 1 );
550const COLOR4D COLOR4D::CLEAR( 1, 0, 1, 0 );
551
552
553double COLOR4D::Distance( const COLOR4D& other ) const
554{
555 return ( r - other.r ) * ( r - other.r )
556 + ( g - other.g ) * ( g - other.g )
557 + ( b - other.b ) * ( b - other.b );
558}
559
560
562{
564
565 /* Find the 'nearest' color in the palette. This is fun. There is
566 a gazilion of metrics for the color space and no one of the
567 useful one is in the RGB color space. Who cares, this is a CAD,
568 not a photosomething...
569
570 I hereby declare that the distance is the sum of the square of the
571 component difference. Think about the RGB color cube. Now get the
572 euclidean distance, but without the square root... for ordering
573 purposes it's the same, obviously. Also each component can't be
574 less of the target one, since I found this currently work better...
575 */
576 int nearest_distance = 255 * 255 * 3 + 1; // Can't beat this
577
579 trying = static_cast<EDA_COLOR_T>( int( trying ) + 1 ) )
580 {
581 const StructColors &c = colorRefs()[trying];
582 int distance = ( aR - c.m_Red ) * ( aR - c.m_Red ) +
583 ( aG - c.m_Green ) * ( aG - c.m_Green ) +
584 ( aB - c.m_Blue ) * ( aB - c.m_Blue );
585
587 c.m_Green >= aG && c.m_Blue >= aB )
588 {
589 nearest_distance = distance;
590 candidate = trying;
591 }
592 }
593
594 return candidate;
595}
596
597
598COLOR4D& COLOR4D::FromCSSRGBA( int aRed, int aGreen, int aBlue, double aAlpha )
599{
600 r = std::clamp( aRed, 0, 255 ) / 255.0;
601 g = std::clamp( aGreen, 0, 255 ) / 255.0;
602 b = std::clamp( aBlue, 0, 255 ) / 255.0;
603 a = std::clamp( aAlpha, 0.0, 1.0 );
604 m_text = std::nullopt;
605
606 return *this;
607}
608
609
610int COLOR4D::Compare( const COLOR4D& aRhs ) const
611{
612 if( m_text.has_value() || aRhs.m_text.has_value() )
613 return ( m_text.value_or( wxEmptyString ) < aRhs.m_text.value_or( wxEmptyString ) ) ? -1 : 1;
614
615 if( r != aRhs.r )
616 return ( r < aRhs.r ) ? -1 : 1;
617
618 if( g != aRhs.g )
619 return ( g < aRhs.g ) ? -1 : 1;
620
621 if( b != aRhs.b )
622 return ( b < aRhs.b ) ? -1 : 1;
623
624 if( a != aRhs.a )
625 return ( a < aRhs.a ) ? -1 : 1;
626
627 return 0;
628}
629
630
632{
633 // Formula from https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
634 double cr = ( r <= 0.04045 ) ? ( r / 12.92 ) : std::pow( ( r + 0.055 ) / 1.055, 2.4 );
635 double cg = ( g <= 0.04045 ) ? ( g / 12.92 ) : std::pow( ( g + 0.055 ) / 1.055, 2.4 );
636 double cb = ( b <= 0.04045 ) ? ( b / 12.92 ) : std::pow( ( b + 0.055 ) / 1.055, 2.4 );
637
638 return 0.2126 * cr + 0.7152 * cg + 0.0722 * cb;
639}
640
641
642double COLOR4D::ContrastRatio( const COLOR4D& aLeft, const COLOR4D& aRight )
643{
644 // Formula from https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
645 double aRL = aLeft.RelativeLuminance();
646 double bRL = aRight.RelativeLuminance();
647
648 if( aRL > bRL )
649 return ( aRL + 0.05 ) / ( bRL + 0.05 );
650 else
651 return ( bRL + 0.05 ) / ( aRL + 0.05 );
652}
int blue
int red
int green
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:990
COLOR4D()
Definition color4d.h:108
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:105
double r
Red component.
Definition color4d.h:393
double g
Green component.
Definition color4d.h:394
static const COLOR4D CLEAR
Definition color4d.h:407
std::optional< wxString > m_text
Definition color4d.h:399
void ToHSV(double &aOutHue, double &aOutSaturation, double &aOutValue, bool aAlwaysDefineHue=false) const
Convert current color (stored in RGB) to HSV format.
Definition color4d.cpp:387
static double ContrastRatio(const COLOR4D &aLeft, const COLOR4D &aRight)
Compute the contrast ration between two colors using the formula from WCAG21.
Definition color4d.cpp:642
void ToHSL(double &aOutHue, double &aOutSaturation, double &aOutLightness) const
Converts current color (stored in RGB) to HSL format.
Definition color4d.cpp:313
bool SetFromWxString(const wxString &aColorString)
Set color values by parsing a string using wxColour::Set().
Definition color4d.cpp:131
bool SetFromHexString(const wxString &aColorString)
Definition color4d.cpp:180
COLOR4D LegacyMix(const COLOR4D &aColor) const
Mix this COLOR4D with an input COLOR4D using the OR-mixing of legacy canvas.
Definition color4d.cpp:236
static EDA_COLOR_T FindNearestLegacyColor(int aR, int aG, int aB)
Returns a legacy color ID that is closest to the given 8-bit RGB values.
Definition color4d.cpp:561
void FromHSV(double aInH, double aInS, double aInV)
Changes currently used color to the one given by hue, saturation and value parameters.
Definition color4d.cpp:441
wxString ToHexString() const
Definition color4d.cpp:215
wxString ToCSSString() const
Definition color4d.cpp:150
int Compare(const COLOR4D &aRhs) const
Definition color4d.cpp:610
static const COLOR4D WHITE
Definition color4d.h:405
double a
Alpha component.
Definition color4d.h:396
double RelativeLuminance() const
Compute the relative luminance of a color using the formula from WCAG21.
Definition color4d.cpp:631
wxColour ToColour() const
Definition color4d.cpp:225
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:402
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition color4d.cpp:532
double Distance(const COLOR4D &other) const
Returns the distance (in RGB space) between two colors.
Definition color4d.cpp:553
void FromHSL(double aInHue, double aInSaturation, double aInLightness)
Change currently used color to the one given by hue, saturation and lightness parameters.
Definition color4d.cpp:344
static const COLOR4D BLACK
Definition color4d.h:406
COLOR4D & FromCSSRGBA(int aRed, int aGreen, int aBlue, double aAlpha=1.0)
Initialize the color from a RGBA value with 0-255 red/green/blue and 0-1 alpha.
Definition color4d.cpp:598
COLOR4D & Saturate(double aFactor)
Saturates the color to a given factor (in HSV model)
Definition color4d.cpp:517
double b
Blue component.
Definition color4d.h:395
const StructColors * colorRefs()
Global list of legacy color names, still used all over the place for constructing COLOR4D's.
Definition color4d.cpp:40
#define TS(string)
Definition color4d.cpp:36
EDA_COLOR_T
Legacy color enumeration.
Definition color4d.h:42
@ LIGHTGREEN
Definition color4d.h:63
@ PUREORANGE
Definition color4d.h:78
@ BROWN
Definition color4d.h:61
@ PURECYAN
Definition color4d.h:70
@ LIGHTBLUE
Definition color4d.h:62
@ WHITE
Definition color4d.h:48
@ LIGHTERORANGE
Definition color4d.h:74
@ LIGHTORANGE
Definition color4d.h:77
@ BLUE
Definition color4d.h:56
@ LIGHTGRAY
Definition color4d.h:47
@ DARKGRAY
Definition color4d.h:46
@ MAGENTA
Definition color4d.h:60
@ DARKORANGE
Definition color4d.h:75
@ DARKMAGENTA
Definition color4d.h:54
@ LIGHTYELLOW
Definition color4d.h:49
@ DARKCYAN
Definition color4d.h:52
@ NBCOLORS
Number of colors.
Definition color4d.h:79
@ PURERED
Definition color4d.h:71
@ GREEN
Definition color4d.h:57
@ CYAN
Definition color4d.h:58
@ DARKRED
Definition color4d.h:53
@ DARKBLUE
Definition color4d.h:50
@ LIGHTCYAN
Definition color4d.h:64
@ DARKDARKGRAY
Definition color4d.h:45
@ ORANGE
Definition color4d.h:76
@ PUREGREEN
Definition color4d.h:69
@ LIGHTMAGENTA
Definition color4d.h:66
@ PUREYELLOW
Definition color4d.h:73
@ YELLOW
Definition color4d.h:67
@ PUREBLUE
Definition color4d.h:68
@ LIGHTRED
Definition color4d.h:65
@ BLACK
Definition color4d.h:44
@ DARKGREEN
Definition color4d.h:51
@ PUREMAGENTA
Definition color4d.h:72
@ RED
Definition color4d.h:59
@ DARKBROWN
Definition color4d.h:55
Some functions to handle hotkeys in KiCad.
The Cairo implementation of the graphics abstraction layer.
Definition eda_group.h:33
void from_json(const nlohmann::json &aJson, COLOR4D &aColor)
Definition color4d.cpp:305
bool operator==(const COLOR4D &lhs, const COLOR4D &rhs)
Equality operator, are two colors equal.
Definition color4d.cpp:254
void to_json(nlohmann::json &aJson, const COLOR4D &aColor)
Definition color4d.cpp:296
bool operator<(const COLOR4D &lhs, const COLOR4D &rhs)
Definition color4d.cpp:269
std::ostream & operator<<(std::ostream &aStream, COLOR4D const &aColor)
Syntactic sugar for outputting colors to strings.
Definition color4d.cpp:287
bool operator!=(const COLOR4D &lhs, const COLOR4D &rhs)
Not equality operator, are two colors not equal.
Definition color4d.cpp:263
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
unsigned char m_Blue
Definition color4d.h:87
unsigned char m_Green
Definition color4d.h:88
unsigned char m_Red
Definition color4d.h:89
int delta