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 return lhs.a == rhs.a && lhs.r == rhs.r && lhs.g == rhs.g && lhs.b == rhs.b;
257}
258
259
260bool operator!=( const COLOR4D& lhs, const COLOR4D& rhs )
261{
262 return !( lhs == rhs );
263}
264
265
266bool operator<( const COLOR4D& lhs, const COLOR4D& rhs )
267{
268 if( lhs.r < rhs.r )
269 return true;
270 else if( lhs.g < rhs.g )
271 return true;
272 else if( lhs.b < rhs.b )
273 return true;
274 else if( lhs.a < rhs.a )
275 return true;
276
277 return false;
278}
279
280
281std::ostream &operator<<( std::ostream &aStream, COLOR4D const &aColor )
282{
283 return aStream << aColor.ToCSSString();
284}
285
286
287void to_json( nlohmann::json& aJson, const COLOR4D& aColor )
288{
289 aJson = nlohmann::json( aColor.ToCSSString().ToStdString() );
290}
291
292
293void from_json( const nlohmann::json& aJson, COLOR4D& aColor )
294{
295 aColor.SetFromWxString( aJson.get<std::string>() );
296}
297
298}
299
300
301void COLOR4D::ToHSL( double& aOutHue, double& aOutSaturation, double& aOutLightness ) const
302{
303 auto min = std::min( r, std::min( g, b ) );
304 auto max = std::max( r, std::max( g, b ) );
305 auto diff = max - min;
306
307 aOutLightness = ( max + min ) / 2.0;
308
309 if( aOutLightness >= 1.0 )
310 aOutSaturation = 0.0;
311 else
312 aOutSaturation = diff / ( 1.0 - std::abs( 2.0 * aOutLightness - 1.0 ) );
313
314 double hue;
315
316 if( diff <= 0.0 )
317 hue = 0.0;
318 else if( max == r )
319 hue = ( g - b ) / diff;
320 else if( max == g )
321 hue = ( b - r ) / diff + 2.0;
322 else
323 hue = ( r - g ) / diff + 4.0;
324
325 aOutHue = hue > 0.0 ? hue * 60.0 : hue * 60.0 + 360.0;
326
327 while( aOutHue < 0.0 )
328 aOutHue += 360.0;
329}
330
331
332void COLOR4D::FromHSL( double aInHue, double aInSaturation, double aInLightness )
333{
334 const auto P = ( 1.0 - std::abs( 2.0 * aInLightness - 1.0 ) ) * aInSaturation;
335 const auto scaled_hue = aInHue / 60.0;
336 const auto Q = P * ( 1.0 - std::abs( std::fmod( scaled_hue, 2.0 ) - 1.0 ) );
337
338 r = g = b = aInLightness - P / 2.0;
339
340 if (scaled_hue < 1.0)
341 {
342 r += P;
343 g += Q;
344 }
345 else if (scaled_hue < 2.0)
346 {
347 r += Q;
348 g += P;
349 }
350 else if (scaled_hue < 3.0)
351 {
352 g += P;
353 b += Q;
354 }
355 else if (scaled_hue < 4.0)
356 {
357 g += Q;
358 b += P;
359 }
360 else if (scaled_hue < 5.0)
361 {
362 r += Q;
363 b += P;
364 }
365 else
366 {
367 r += P;
368 b += Q;
369 }
370
371 m_text = std::nullopt;
372}
373
374
375void COLOR4D::ToHSV( double& aOutHue, double& aOutSaturation, double& aOutValue,
376 bool aAlwaysDefineHue ) const
377{
378 double min, max, delta;
379
380 min = r < g ? r : g;
381 min = min < b ? min : b;
382
383 max = r > g ? r : g;
384 max = max > b ? max : b;
385
386 aOutValue = max; // value
387 delta = max - min;
388
389 if( max > 0.0 )
390 {
391 aOutSaturation = ( delta / max );
392 }
393 else // for black color (r = g = b = 0 ) saturation is set to 0.
394 {
395 aOutSaturation = 0.0;
396 aOutHue = aAlwaysDefineHue ? 0.0 : NAN;
397 return;
398 }
399
400 /* Hue in degrees (0...360) is coded according to this table
401 * 0 or 360 : red
402 * 60 : yellow
403 * 120 : green
404 * 180 : cyan
405 * 240 : blue
406 * 300 : magenta
407 */
408 if( delta != 0.0 )
409 {
410 if( r >= max )
411 aOutHue = ( g - b ) / delta; // between yellow & magenta
412 else if( g >= max )
413 aOutHue = 2.0 + ( b - r ) / delta; // between cyan & yellow
414 else
415 aOutHue = 4.0 + ( r - g ) / delta; // between magenta & cyan
416
417 aOutHue *= 60.0; // degrees
418
419 if( aOutHue < 0.0 )
420 aOutHue += 360.0;
421 }
422 else // delta = 0 means r = g = b. hue is set to 0.0
423 {
424 aOutHue = aAlwaysDefineHue ? 0.0 : NAN;
425 }
426}
427
428
429void COLOR4D::FromHSV( double aInH, double aInS, double aInV )
430{
431 if( aInS <= 0.0 )
432 {
433 r = aInV;
434 g = aInV;
435 b = aInV;
436 return;
437 }
438
439 double hh = aInH;
440
441 while( hh >= 360.0 )
442 hh -= 360.0;
443
444 /* Hue in degrees (0...360) is coded according to this table
445 * 0 or 360 : red
446 * 60 : yellow
447 * 120 : green
448 * 180 : cyan
449 * 240 : blue
450 * 300 : magenta
451 */
452 hh /= 60.0;
453
454 int i = (int) hh;
455 double ff = hh - i;
456
457 double p = aInV * ( 1.0 - aInS );
458 double q = aInV * ( 1.0 - ( aInS * ff ) );
459 double t = aInV * ( 1.0 - ( aInS * ( 1.0 - ff ) ) );
460
461 switch( i )
462 {
463 case 0:
464 r = aInV;
465 g = t;
466 b = p;
467 break;
468
469 case 1:
470 r = q;
471 g = aInV;
472 b = p;
473 break;
474
475 case 2:
476 r = p;
477 g = aInV;
478 b = t;
479 break;
480
481 case 3:
482 r = p;
483 g = q;
484 b = aInV;
485 break;
486
487 case 4:
488 r = t;
489 g = p;
490 b = aInV;
491 break;
492
493 case 5:
494 default:
495 r = aInV;
496 g = p;
497 b = q;
498 break;
499 }
500
501 m_text = std::nullopt;
502}
503
504
505COLOR4D& COLOR4D::Saturate( double aFactor )
506{
507 // One can saturate a color only when r, v, b are not equal
508 if( r == g && r == b )
509 return *this;
510
511 double h, s, v;
512
513 ToHSV( h, s, v, true );
514 FromHSV( h, aFactor, 1.0 );
515
516 return *this;
517}
518
519
521{
522 // One can desaturate a color only when r, v, b are not equal
523 if( r == g && r == b )
524 return *this;
525
526 double h, s, l;
527
528 ToHSL( h, s, l );
529 FromHSL( h, 0.0, l );
530
531 return *this;
532}
533
534
535const COLOR4D COLOR4D::UNSPECIFIED( 0, 0, 0, 0 );
536const COLOR4D COLOR4D::WHITE( 1, 1, 1, 1 );
537const COLOR4D COLOR4D::BLACK( 0, 0, 0, 1 );
538const COLOR4D COLOR4D::CLEAR( 1, 0, 1, 0 );
539
540
541double COLOR4D::Distance( const COLOR4D& other ) const
542{
543 return ( r - other.r ) * ( r - other.r )
544 + ( g - other.g ) * ( g - other.g )
545 + ( b - other.b ) * ( b - other.b );
546}
547
548
550{
552
553 /* Find the 'nearest' color in the palette. This is fun. There is
554 a gazilion of metrics for the color space and no one of the
555 useful one is in the RGB color space. Who cares, this is a CAD,
556 not a photosomething...
557
558 I hereby declare that the distance is the sum of the square of the
559 component difference. Think about the RGB color cube. Now get the
560 euclidean distance, but without the square root... for ordering
561 purposes it's the same, obviously. Also each component can't be
562 less of the target one, since I found this currently work better...
563 */
564 int nearest_distance = 255 * 255 * 3 + 1; // Can't beat this
565
567 trying = static_cast<EDA_COLOR_T>( int( trying ) + 1 ) )
568 {
569 const StructColors &c = colorRefs()[trying];
570 int distance = ( aR - c.m_Red ) * ( aR - c.m_Red ) +
571 ( aG - c.m_Green ) * ( aG - c.m_Green ) +
572 ( aB - c.m_Blue ) * ( aB - c.m_Blue );
573
575 c.m_Green >= aG && c.m_Blue >= aB )
576 {
577 nearest_distance = distance;
578 candidate = trying;
579 }
580 }
581
582 return candidate;
583}
584
585
586COLOR4D& COLOR4D::FromCSSRGBA( int aRed, int aGreen, int aBlue, double aAlpha )
587{
588 r = std::clamp( aRed, 0, 255 ) / 255.0;
589 g = std::clamp( aGreen, 0, 255 ) / 255.0;
590 b = std::clamp( aBlue, 0, 255 ) / 255.0;
591 a = std::clamp( aAlpha, 0.0, 1.0 );
592 m_text = std::nullopt;
593
594 return *this;
595}
596
597
598int COLOR4D::Compare( const COLOR4D& aRhs ) const
599{
600 if( m_text.has_value() && aRhs.m_text.has_value() )
601 {
602 if( m_text.value() == aRhs.m_text.value() )
603 return 0;
604 else
605 return m_text.value() < aRhs.m_text.value() ? -1 : 1;
606 }
607 else if( m_text.has_value() )
608 {
609 return -1;
610 }
611 else if( aRhs.m_text.has_value() )
612 {
613 return 1;
614 }
615
616 if( r != aRhs.r )
617 return ( r < aRhs.r ) ? -1 : 1;
618
619 if( g != aRhs.g )
620 return ( g < aRhs.g ) ? -1 : 1;
621
622 if( b != aRhs.b )
623 return ( b < aRhs.b ) ? -1 : 1;
624
625 if( a != aRhs.a )
626 return ( a < aRhs.a ) ? -1 : 1;
627
628 return 0;
629}
630
631
633{
634 // Formula from https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
635 double cr = ( r <= 0.04045 ) ? ( r / 12.92 ) : std::pow( ( r + 0.055 ) / 1.055, 2.4 );
636 double cg = ( g <= 0.04045 ) ? ( g / 12.92 ) : std::pow( ( g + 0.055 ) / 1.055, 2.4 );
637 double cb = ( b <= 0.04045 ) ? ( b / 12.92 ) : std::pow( ( b + 0.055 ) / 1.055, 2.4 );
638
639 return 0.2126 * cr + 0.7152 * cg + 0.0722 * cb;
640}
641
642
643double COLOR4D::ContrastRatio( const COLOR4D& aLeft, const COLOR4D& aRight )
644{
645 // Formula from https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
646 double aRL = aLeft.RelativeLuminance();
647 double bRL = aRight.RelativeLuminance();
648
649 if( aRL > bRL )
650 return ( aRL + 0.05 ) / ( bRL + 0.05 );
651 else
652 return ( bRL + 0.05 ) / ( aRL + 0.05 );
653}
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:375
static double ContrastRatio(const COLOR4D &aLeft, const COLOR4D &aRight)
Compute the contrast ration between two colors using the formula from WCAG21.
Definition color4d.cpp:643
void ToHSL(double &aOutHue, double &aOutSaturation, double &aOutLightness) const
Converts current color (stored in RGB) to HSL format.
Definition color4d.cpp:301
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:549
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:429
wxString ToHexString() const
Definition color4d.cpp:215
wxString ToCSSString() const
Definition color4d.cpp:150
int Compare(const COLOR4D &aRhs) const
Definition color4d.cpp:598
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:632
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:520
double Distance(const COLOR4D &other) const
Returns the distance (in RGB space) between two colors.
Definition color4d.cpp:541
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:332
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:586
COLOR4D & Saturate(double aFactor)
Saturates the color to a given factor (in HSV model)
Definition color4d.cpp:505
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:293
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:287
bool operator<(const COLOR4D &lhs, const COLOR4D &rhs)
Definition color4d.cpp:266
std::ostream & operator<<(std::ostream &aStream, COLOR4D const &aColor)
Syntactic sugar for outputting colors to strings.
Definition color4d.cpp:281
bool operator!=(const COLOR4D &lhs, const COLOR4D &rhs)
Not equality operator, are two colors not equal.
Definition color4d.cpp:260
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