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