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 == 0.0 )
318 aOutSaturation = 0.0;
319 else if( aOutLightness >= 1.0 )
320 aOutSaturation = 0.0;
321 else
322 aOutSaturation = diff / ( 1.0 - std::abs( 2.0 * aOutLightness - 1.0 ) );
323
324 double hue;
325
326 if( diff <= 0.0 )
327 hue = 0.0;
328 else if( max == r )
329 hue = ( g - b ) / diff;
330 else if( max == g )
331 hue = ( b - r ) / diff + 2.0;
332 else
333 hue = ( r - g ) / diff + 4.0;
334
335 aOutHue = hue > 0.0 ? hue * 60.0 : hue * 60.0 + 360.0;
336
337 while( aOutHue < 0.0 )
338 aOutHue += 360.0;
339}
340
341
342void COLOR4D::FromHSL( double aInHue, double aInSaturation, double aInLightness )
343{
344 const auto P = ( 1.0 - std::abs( 2.0 * aInLightness - 1.0 ) ) * aInSaturation;
345 const auto scaled_hue = aInHue / 60.0;
346 const auto Q = P * ( 1.0 - std::abs( std::fmod( scaled_hue, 2.0 ) - 1.0 ) );
347
348 r = g = b = aInLightness - P / 2.0;
349
350 if (scaled_hue < 1.0)
351 {
352 r += P;
353 g += Q;
354 }
355 else if (scaled_hue < 2.0)
356 {
357 r += Q;
358 g += P;
359 }
360 else if (scaled_hue < 3.0)
361 {
362 g += P;
363 b += Q;
364 }
365 else if (scaled_hue < 4.0)
366 {
367 g += Q;
368 b += P;
369 }
370 else if (scaled_hue < 5.0)
371 {
372 r += Q;
373 b += P;
374 }
375 else
376 {
377 r += P;
378 b += Q;
379 }
380
381 m_text = nullptr;
382}
383
384
385void COLOR4D::ToHSV( double& aOutHue, double& aOutSaturation, double& aOutValue,
386 bool aAlwaysDefineHue ) const
387{
388 double min, max, delta;
389
390 min = r < g ? r : g;
391 min = min < b ? min : b;
392
393 max = r > g ? r : g;
394 max = max > b ? max : b;
395
396 aOutValue = max; // value
397 delta = max - min;
398
399 if( max > 0.0 )
400 {
401 aOutSaturation = ( delta / max );
402 }
403 else // for black color (r = g = b = 0 ) saturation is set to 0.
404 {
405 aOutSaturation = 0.0;
406 aOutHue = aAlwaysDefineHue ? 0.0 : NAN;
407 return;
408 }
409
410 /* Hue in degrees (0...360) is coded according to this table
411 * 0 or 360 : red
412 * 60 : yellow
413 * 120 : green
414 * 180 : cyan
415 * 240 : blue
416 * 300 : magenta
417 */
418 if( delta != 0.0 )
419 {
420 if( r >= max )
421 aOutHue = ( g - b ) / delta; // between yellow & magenta
422 else if( g >= max )
423 aOutHue = 2.0 + ( b - r ) / delta; // between cyan & yellow
424 else
425 aOutHue = 4.0 + ( r - g ) / delta; // between magenta & cyan
426
427 aOutHue *= 60.0; // degrees
428
429 if( aOutHue < 0.0 )
430 aOutHue += 360.0;
431 }
432 else // delta = 0 means r = g = b. hue is set to 0.0
433 {
434 aOutHue = aAlwaysDefineHue ? 0.0 : NAN;
435 }
436}
437
438
439void COLOR4D::FromHSV( double aInH, double aInS, double aInV )
440{
441 if( aInS <= 0.0 )
442 {
443 r = aInV;
444 g = aInV;
445 b = aInV;
446 return;
447 }
448
449 double hh = aInH;
450
451 while( hh >= 360.0 )
452 hh -= 360.0;
453
454 /* Hue in degrees (0...360) is coded according to this table
455 * 0 or 360 : red
456 * 60 : yellow
457 * 120 : green
458 * 180 : cyan
459 * 240 : blue
460 * 300 : magenta
461 */
462 hh /= 60.0;
463
464 int i = (int) hh;
465 double ff = hh - i;
466
467 double p = aInV * ( 1.0 - aInS );
468 double q = aInV * ( 1.0 - ( aInS * ff ) );
469 double t = aInV * ( 1.0 - ( aInS * ( 1.0 - ff ) ) );
470
471 switch( i )
472 {
473 case 0:
474 r = aInV;
475 g = t;
476 b = p;
477 break;
478
479 case 1:
480 r = q;
481 g = aInV;
482 b = p;
483 break;
484
485 case 2:
486 r = p;
487 g = aInV;
488 b = t;
489 break;
490
491 case 3:
492 r = p;
493 g = q;
494 b = aInV;
495 break;
496
497 case 4:
498 r = t;
499 g = p;
500 b = aInV;
501 break;
502
503 case 5:
504 default:
505 r = aInV;
506 g = p;
507 b = q;
508 break;
509 }
510
511 m_text = nullptr;
512}
513
514
515COLOR4D& COLOR4D::Saturate( double aFactor )
516{
517 // One can saturate a color only when r, v, b are not equal
518 if( r == g && r == b )
519 return *this;
520
521 double h, s, v;
522
523 ToHSV( h, s, v, true );
524 FromHSV( h, aFactor, 1.0 );
525
526 return *this;
527}
528
529
531{
532 // One can desaturate a color only when r, v, b are not equal
533 if( r == g && r == b )
534 return *this;
535
536 double h, s, l;
537
538 ToHSL( h, s, l );
539 FromHSL( h, 0.0, l );
540
541 return *this;
542}
543
544
545const COLOR4D COLOR4D::UNSPECIFIED( 0, 0, 0, 0 );
546const COLOR4D COLOR4D::WHITE( 1, 1, 1, 1 );
547const COLOR4D COLOR4D::BLACK( 0, 0, 0, 1 );
548const COLOR4D COLOR4D::CLEAR( 1, 0, 1, 0 );
549
550
551double COLOR4D::Distance( const COLOR4D& other ) const
552{
553 return ( r - other.r ) * ( r - other.r )
554 + ( g - other.g ) * ( g - other.g )
555 + ( b - other.b ) * ( b - other.b );
556}
557
558
560{
562
563 /* Find the 'nearest' color in the palette. This is fun. There is
564 a gazilion of metrics for the color space and no one of the
565 useful one is in the RGB color space. Who cares, this is a CAD,
566 not a photosomething...
567
568 I hereby declare that the distance is the sum of the square of the
569 component difference. Think about the RGB color cube. Now get the
570 euclidean distance, but without the square root... for ordering
571 purposes it's the same, obviously. Also each component can't be
572 less of the target one, since I found this currently work better...
573 */
574 int nearest_distance = 255 * 255 * 3 + 1; // Can't beat this
575
577 trying = static_cast<EDA_COLOR_T>( int( trying ) + 1 ) )
578 {
579 const StructColors &c = colorRefs()[trying];
580 int distance = ( aR - c.m_Red ) * ( aR - c.m_Red ) +
581 ( aG - c.m_Green ) * ( aG - c.m_Green ) +
582 ( aB - c.m_Blue ) * ( aB - c.m_Blue );
583
585 c.m_Green >= aG && c.m_Blue >= aB )
586 {
587 nearest_distance = distance;
588 candidate = trying;
589 }
590 }
591
592 return candidate;
593}
594
595
596COLOR4D& COLOR4D::FromCSSRGBA( int aRed, int aGreen, int aBlue, double aAlpha )
597{
598 r = std::clamp( aRed, 0, 255 ) / 255.0;
599 g = std::clamp( aGreen, 0, 255 ) / 255.0;
600 b = std::clamp( aBlue, 0, 255 ) / 255.0;
601 a = std::clamp( aAlpha, 0.0, 1.0 );
602 m_text = nullptr;
603
604 return *this;
605}
606
607
608int COLOR4D::Compare( const COLOR4D& aRhs ) const
609{
610 if( m_text || aRhs.m_text )
611 {
612 return ( ( m_text ? *m_text : wxString() ) < ( aRhs.m_text ? *aRhs.m_text : wxString() ) ) ? -1 : 1;
613 }
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:995
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:390
double g
Green component.
Definition color4d.h:391
static const COLOR4D CLEAR
Definition color4d.h:404
void ToHSV(double &aOutHue, double &aOutSaturation, double &aOutValue, bool aAlwaysDefineHue=false) const
Convert current color (stored in RGB) to HSV format.
Definition color4d.cpp:385
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: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:559
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:439
wxString ToHexString() const
Definition color4d.cpp:211
wxString ToCSSString() const
Definition color4d.cpp:146
int Compare(const COLOR4D &aRhs) const
Definition color4d.cpp:608
static const COLOR4D WHITE
Definition color4d.h:402
std::shared_ptr< wxString > m_text
Definition color4d.h:396
double a
Alpha component.
Definition color4d.h:393
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:221
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:399
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition color4d.cpp:530
double Distance(const COLOR4D &other) const
Returns the distance (in RGB space) between two colors.
Definition color4d.cpp:551
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:342
static const COLOR4D BLACK
Definition color4d.h:403
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:596
COLOR4D & Saturate(double aFactor)
Saturates the color to a given factor (in HSV model)
Definition color4d.cpp:515
double b
Blue component.
Definition color4d.h:392
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:30
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:411
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