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 2017-2023 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 <nlohmann/json.hpp>
28#include <gal/color4d.h>
29#include <i18n_utility.h>
30#include <wx/crt.h>
31#include <math/util.h>
32
33using namespace KIGFX;
34
35#define TS( string ) wxString( _HKI( string ) ).ToStdString()
36
37// We can't have this as a plain static variable, because it is referenced during the initialization
38// of other static variables, so we must initialize it explicitly on first use.
40{
41 static StructColors s_ColorRefs[NBCOLORS] =
42 {
43 { 0, 0, 0, BLACK, TS( "Black" ), DARKDARKGRAY },
44 { 72, 72, 72, DARKDARKGRAY, TS( "Gray 1" ), DARKGRAY },
45 { 132, 132, 132, DARKGRAY, TS( "Gray 2" ), LIGHTGRAY },
46 { 194, 194, 194, LIGHTGRAY, TS( "Gray 3" ), WHITE },
47 { 255, 255, 255, WHITE, TS( "White" ), WHITE },
48 { 194, 255, 255, LIGHTYELLOW, TS( "L.Yellow" ), WHITE },
49 { 191, 229, 255, LIGHTERORANGE, TS( "L.Orange" ), WHITE },
50 { 72, 0, 0, DARKBLUE, TS( "Blue 1" ), BLUE },
51 { 0, 72, 0, DARKGREEN, TS( "Green 1" ), GREEN },
52 { 72, 72, 0, DARKCYAN, TS( "Cyan 1" ), CYAN },
53 { 0, 0, 72, DARKRED, TS( "Red 1" ), RED },
54 { 72, 0, 72, DARKMAGENTA, TS( "Magenta 1" ), MAGENTA },
55 { 0, 72, 72, DARKBROWN, TS( "Brown 1" ), BROWN },
56 { 0, 77, 128, DARKORANGE, TS( "Orange 1" ), ORANGE },
57 { 132, 0, 0, BLUE, TS( "Blue 2" ), LIGHTBLUE },
58 { 0, 132, 0, GREEN, TS( "Green 2" ), LIGHTGREEN },
59 { 132, 132, 0, CYAN, TS( "Cyan 2" ), LIGHTCYAN },
60 { 0, 0, 132, RED, TS( "Red 2" ), LIGHTRED },
61 { 132, 0, 132, MAGENTA, TS( "Magenta 2" ), LIGHTMAGENTA },
62 { 0, 132, 132, BROWN, TS( "Brown 2" ), YELLOW },
63 { 0, 102, 204, ORANGE, TS( "Orange 2" ), LIGHTORANGE },
64 { 194, 0, 0, LIGHTBLUE, TS( "Blue 3" ), PUREBLUE, },
65 { 0, 194, 0, LIGHTGREEN, TS( "Green 3" ), PUREGREEN },
66 { 194, 194, 0, LIGHTCYAN, TS( "Cyan 3" ), PURECYAN },
67 { 0, 0, 194, LIGHTRED, TS( "Red 3" ), PURERED },
68 { 194, 0, 194, LIGHTMAGENTA, TS( "Magenta 3" ), PUREMAGENTA },
69 { 0, 194, 194, YELLOW, TS( "Yellow 3" ), PUREYELLOW },
70 { 0, 133, 221, LIGHTORANGE, TS( "Orange 3" ), PUREORANGE },
71 { 255, 0, 0, PUREBLUE, TS( "Blue 4" ), WHITE },
72 { 0, 255, 0, PUREGREEN, TS( "Green 4" ), WHITE },
73 { 255, 255, 0, PURECYAN, TS( "Cyan 4" ), WHITE },
74 { 0, 0, 255, PURERED, TS( "Red 4" ), WHITE },
75 { 255, 0, 255, PUREMAGENTA, TS( "Magenta 4" ), WHITE },
76 { 0, 255, 255, PUREYELLOW, TS( "Yellow 4" ), WHITE },
77 { 0, 153, 255, PUREORANGE, TS( "Orange 4" ), WHITE },
78 };
79 return s_ColorRefs;
80}
81
82
84{
85 if( aColor <= UNSPECIFIED_COLOR || aColor >= NBCOLORS )
86 {
88 return;
89 }
90
91 int candidate = 0;
92
93 for( ; candidate < NBCOLORS; ++candidate )
94 {
95 if( colorRefs()[candidate].m_Numcolor == aColor )
96 break;
97 }
98
99 if( candidate >= NBCOLORS )
100 {
101 *this = COLOR4D::UNSPECIFIED;
102 return;
103 }
104
105 r = colorRefs()[candidate].m_Red / 255.0;
106 g = colorRefs()[candidate].m_Green / 255.0;
107 b = colorRefs()[candidate].m_Blue / 255.0;
108 a = 1.0;
109}
110
111
112COLOR4D::COLOR4D( const wxString& aColorStr )
113{
114 if( !SetFromHexString( aColorStr ) )
115 SetFromWxString( aColorStr );
116}
117
118
119COLOR4D::COLOR4D( const wxColour& aColor )
120{
121 r = aColor.Red() / 255.0;
122 g = aColor.Green() / 255.0;
123 b = aColor.Blue() / 255.0;
124 a = aColor.Alpha() / 255.0;
125}
126
127
128bool COLOR4D::SetFromWxString( const wxString& aColorString )
129{
130 wxColour c;
131
132 if( c.Set( aColorString ) )
133 {
134 r = c.Red() / 255.0;
135 g = c.Green() / 255.0;
136 b = c.Blue() / 255.0;
137 a = c.Alpha() / 255.0;
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 return true;
206}
207
208
209wxString COLOR4D::ToHexString() const
210{
211 return wxString::Format( wxT("#%02X%02X%02X%02X" ),
212 KiROUND( r * 255.0 ),
213 KiROUND( g * 255.0 ),
214 KiROUND( b * 255.0 ),
215 KiROUND( a * 255.0 ) );
216}
217
218
219wxColour COLOR4D::ToColour() const
220{
221 using CHAN_T = wxColourBase::ChannelType;
222
223 const wxColour colour(
224 static_cast<CHAN_T>( r * 255 + 0.5 ), static_cast<CHAN_T>( g * 255 + 0.5 ),
225 static_cast<CHAN_T>( b * 255 + 0.5 ), static_cast<CHAN_T>( a * 255 + 0.5 ) );
226 return colour;
227}
228
229
230COLOR4D COLOR4D::LegacyMix( const COLOR4D& aColor ) const
231{
232 COLOR4D candidate;
233
234 // Blend the two colors (i.e. OR the RGB values)
235 candidate.r = ( (unsigned) ( 255.0 * r ) | (unsigned) ( 255.0 * aColor.r ) ) / 255.0,
236 candidate.g = ( (unsigned) ( 255.0 * g ) | (unsigned) ( 255.0 * aColor.g ) ) / 255.0,
237 candidate.b = ( (unsigned) ( 255.0 * b ) | (unsigned) ( 255.0 * aColor.b ) ) / 255.0,
238
239 // the alpha channel can be reinitialized but what is the best value?
240 candidate.a = ( aColor.a + a ) / 2;
241
242 return candidate;
243}
244
245
246namespace KIGFX {
247
248bool operator==( const COLOR4D& lhs, const COLOR4D& rhs )
249{
250 return lhs.a == rhs.a && lhs.r == rhs.r && lhs.g == rhs.g && lhs.b == rhs.b;
251}
252
253
254bool operator!=( const COLOR4D& lhs, const COLOR4D& rhs )
255{
256 return !( lhs == rhs );
257}
258
259
260bool operator<( const COLOR4D& lhs, const COLOR4D& rhs )
261{
262 if( lhs.r < rhs.r )
263 return true;
264 else if( lhs.g < rhs.g )
265 return true;
266 else if( lhs.b < rhs.b )
267 return true;
268 else if( lhs.a < rhs.a )
269 return true;
270
271 return false;
272}
273
274
275std::ostream &operator<<( std::ostream &aStream, COLOR4D const &aColor )
276{
277 return aStream << aColor.ToCSSString();
278}
279
280
281void to_json( nlohmann::json& aJson, const COLOR4D& aColor )
282{
283 aJson = nlohmann::json( aColor.ToCSSString().ToStdString() );
284}
285
286
287void from_json( const nlohmann::json& aJson, COLOR4D& aColor )
288{
289 aColor.SetFromWxString( aJson.get<std::string>() );
290}
291
292}
293
294
295void COLOR4D::ToHSL( double& aOutHue, double& aOutSaturation, double& aOutLightness ) const
296{
297 auto min = std::min( r, std::min( g, b ) );
298 auto max = std::max( r, std::max( g, b ) );
299 auto diff = max - min;
300
301 aOutLightness = ( max + min ) / 2.0;
302
303 if( aOutLightness >= 1.0 )
304 aOutSaturation = 0.0;
305 else
306 aOutSaturation = diff / ( 1.0 - std::abs( 2.0 * aOutLightness - 1.0 ) );
307
308 double hue;
309
310 if( diff <= 0.0 )
311 hue = 0.0;
312 else if( max == r )
313 hue = ( g - b ) / diff;
314 else if( max == g )
315 hue = ( b - r ) / diff + 2.0;
316 else
317 hue = ( r - g ) / diff + 4.0;
318
319 aOutHue = hue > 0.0 ? hue * 60.0 : hue * 60.0 + 360.0;
320
321 while( aOutHue < 0.0 )
322 aOutHue += 360.0;
323}
324
325
326void COLOR4D::FromHSL( double aInHue, double aInSaturation, double aInLightness )
327{
328 const auto P = ( 1.0 - std::abs( 2.0 * aInLightness - 1.0 ) ) * aInSaturation;
329 const auto scaled_hue = aInHue / 60.0;
330 const auto Q = P * ( 1.0 - std::abs( std::fmod( scaled_hue, 2.0 ) - 1.0 ) );
331
332 r = g = b = aInLightness - P / 2.0;
333
334 if (scaled_hue < 1.0)
335 {
336 r += P;
337 g += Q;
338 }
339 else if (scaled_hue < 2.0)
340 {
341 r += Q;
342 g += P;
343 }
344 else if (scaled_hue < 3.0)
345 {
346 g += P;
347 b += Q;
348 }
349 else if (scaled_hue < 4.0)
350 {
351 g += Q;
352 b += P;
353 }
354 else if (scaled_hue < 5.0)
355 {
356 r += Q;
357 b += P;
358 }
359 else
360 {
361 r += P;
362 b += Q;
363 }
364}
365
366
367void COLOR4D::ToHSV( double& aOutHue, double& aOutSaturation, double& aOutValue,
368 bool aAlwaysDefineHue ) const
369{
370 double min, max, delta;
371
372 min = r < g ? r : g;
373 min = min < b ? min : b;
374
375 max = r > g ? r : g;
376 max = max > b ? max : b;
377
378 aOutValue = max; // value
379 delta = max - min;
380
381 if( max > 0.0 )
382 {
383 aOutSaturation = ( delta / max );
384 }
385 else // for black color (r = g = b = 0 ) saturation is set to 0.
386 {
387 aOutSaturation = 0.0;
388 aOutHue = aAlwaysDefineHue ? 0.0 : NAN;
389 return;
390 }
391
392 /* Hue in degrees (0...360) is coded according to this table
393 * 0 or 360 : red
394 * 60 : yellow
395 * 120 : green
396 * 180 : cyan
397 * 240 : blue
398 * 300 : magenta
399 */
400 if( delta != 0.0 )
401 {
402 if( r >= max )
403 aOutHue = ( g - b ) / delta; // between yellow & magenta
404 else if( g >= max )
405 aOutHue = 2.0 + ( b - r ) / delta; // between cyan & yellow
406 else
407 aOutHue = 4.0 + ( r - g ) / delta; // between magenta & cyan
408
409 aOutHue *= 60.0; // degrees
410
411 if( aOutHue < 0.0 )
412 aOutHue += 360.0;
413 }
414 else // delta = 0 means r = g = b. hue is set to 0.0
415 {
416 aOutHue = aAlwaysDefineHue ? 0.0 : NAN;
417 }
418}
419
420
421void COLOR4D::FromHSV( double aInH, double aInS, double aInV )
422{
423 if( aInS <= 0.0 )
424 {
425 r = aInV;
426 g = aInV;
427 b = aInV;
428 return;
429 }
430
431 double hh = aInH;
432
433 while( hh >= 360.0 )
434 hh -= 360.0;
435
436 /* Hue in degrees (0...360) is coded according to this table
437 * 0 or 360 : red
438 * 60 : yellow
439 * 120 : green
440 * 180 : cyan
441 * 240 : blue
442 * 300 : magenta
443 */
444 hh /= 60.0;
445
446 int i = (int) hh;
447 double ff = hh - i;
448
449 double p = aInV * ( 1.0 - aInS );
450 double q = aInV * ( 1.0 - ( aInS * ff ) );
451 double t = aInV * ( 1.0 - ( aInS * ( 1.0 - ff ) ) );
452
453 switch( i )
454 {
455 case 0:
456 r = aInV;
457 g = t;
458 b = p;
459 break;
460
461 case 1:
462 r = q;
463 g = aInV;
464 b = p;
465 break;
466
467 case 2:
468 r = p;
469 g = aInV;
470 b = t;
471 break;
472
473 case 3:
474 r = p;
475 g = q;
476 b = aInV;
477 break;
478
479 case 4:
480 r = t;
481 g = p;
482 b = aInV;
483 break;
484
485 case 5:
486 default:
487 r = aInV;
488 g = p;
489 b = q;
490 break;
491 }
492}
493
494
495COLOR4D& COLOR4D::Saturate( double aFactor )
496{
497 // One can saturate a color only when r, v, b are not equal
498 if( r == g && r == b )
499 return *this;
500
501 double h, s, v;
502
503 ToHSV( h, s, v, true );
504 FromHSV( h, aFactor, 1.0 );
505
506 return *this;
507}
508
509
511{
512 // One can desaturate a color only when r, v, b are not equal
513 if( r == g && r == b )
514 return *this;
515
516 double h, s, l;
517
518 ToHSL( h, s, l );
519 FromHSL( h, 0.0, l );
520
521 return *this;
522}
523
524
525const COLOR4D COLOR4D::UNSPECIFIED( 0, 0, 0, 0 );
526const COLOR4D COLOR4D::WHITE( 1, 1, 1, 1 );
527const COLOR4D COLOR4D::BLACK( 0, 0, 0, 1 );
528const COLOR4D COLOR4D::CLEAR( 1, 0, 1, 0 );
529
530
531double COLOR4D::Distance( const COLOR4D& other ) const
532{
533 return ( r - other.r ) * ( r - other.r )
534 + ( g - other.g ) * ( g - other.g )
535 + ( b - other.b ) * ( b - other.b );
536}
537
538
540{
541 EDA_COLOR_T candidate = EDA_COLOR_T::BLACK;
542
543 /* Find the 'nearest' color in the palette. This is fun. There is
544 a gazilion of metrics for the color space and no one of the
545 useful one is in the RGB color space. Who cares, this is a CAD,
546 not a photosomething...
547
548 I hereby declare that the distance is the sum of the square of the
549 component difference. Think about the RGB color cube. Now get the
550 euclidean distance, but without the square root... for ordering
551 purposes it's the same, obviously. Also each component can't be
552 less of the target one, since I found this currently work better...
553 */
554 int nearest_distance = 255 * 255 * 3 + 1; // Can't beat this
555
556 for( EDA_COLOR_T trying = EDA_COLOR_T::BLACK; trying < EDA_COLOR_T::NBCOLORS;
557 trying = static_cast<EDA_COLOR_T>( int( trying ) + 1 ) )
558 {
559 const StructColors &c = colorRefs()[trying];
560 int distance = ( aR - c.m_Red ) * ( aR - c.m_Red ) +
561 ( aG - c.m_Green ) * ( aG - c.m_Green ) +
562 ( aB - c.m_Blue ) * ( aB - c.m_Blue );
563
564 if( distance < nearest_distance && c.m_Red >= aR &&
565 c.m_Green >= aG && c.m_Blue >= aB )
566 {
567 nearest_distance = distance;
568 candidate = trying;
569 }
570 }
571
572 return candidate;
573}
574
575
576COLOR4D& COLOR4D::FromCSSRGBA( int aRed, int aGreen, int aBlue, double aAlpha )
577{
578 r = std::max( 0, std::min( 255, aRed ) ) / 255.0;
579 g = std::max( 0, std::min( 255, aGreen ) ) / 255.0;
580 b = std::max( 0, std::min( 255, aBlue ) ) / 255.0;
581 a = std::max( 0.0, std::min( 1.0, aAlpha ) );
582
583 return *this;
584}
585
586
587int COLOR4D::Compare( const COLOR4D& aRhs ) const
588{
589 if( r != aRhs.r )
590 return ( r < aRhs.r ) ? -1 : 1;
591
592 if( g != aRhs.g )
593 return ( g < aRhs.g ) ? -1 : 1;
594
595 if( b != aRhs.b )
596 return ( b < aRhs.b ) ? -1 : 1;
597
598 if( a != aRhs.a )
599 return ( a < aRhs.a ) ? -1 : 1;
600
601 return 0;
602}
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103
void ToHSL(double &aOutHue, double &aOutSaturation, double &aOutValue) const
Converts current color (stored in RGB) to HSL format.
Definition: color4d.cpp:295
double r
Red component.
Definition: color4d.h:375
double g
Green component.
Definition: color4d.h:376
static const COLOR4D CLEAR
Definition: color4d.h:386
void ToHSV(double &aOutHue, double &aOutSaturation, double &aOutValue, bool aAlwaysDefineHue=false) const
Convert current color (stored in RGB) to HSV format.
Definition: color4d.cpp:367
bool SetFromWxString(const wxString &aColorString)
Set color values by parsing a string using wxColour::Set().
Definition: color4d.cpp:128
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:230
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:539
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:421
wxString ToHexString() const
Definition: color4d.cpp:209
wxString ToCSSString() const
Definition: color4d.cpp:146
int Compare(const COLOR4D &aRhs) const
Definition: color4d.cpp:587
static const COLOR4D WHITE
Definition: color4d.h:384
double a
Alpha component.
Definition: color4d.h:378
wxColour ToColour() const
Definition: color4d.cpp:219
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition: color4d.h:381
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition: color4d.cpp:510
double Distance(const COLOR4D &other) const
Returns the distance (in RGB space) between two colors.
Definition: color4d.cpp:531
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:326
static const COLOR4D BLACK
Definition: color4d.h:385
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:576
COLOR4D & Saturate(double aFactor)
Saturates the color to a given factor (in HSV model)
Definition: color4d.cpp:495
double b
Blue component.
Definition: color4d.h:377
const StructColors * colorRefs()
Global list of legacy color names, still used all over the place for constructing COLOR4D's.
Definition: color4d.cpp:39
#define TS(string)
Definition: color4d.cpp:35
EDA_COLOR_T
Legacy color enumeration.
Definition: color4d.h:41
@ LIGHTGREEN
Definition: color4d.h:62
@ PUREORANGE
Definition: color4d.h:77
@ BROWN
Definition: color4d.h:60
@ PURECYAN
Definition: color4d.h:69
@ LIGHTBLUE
Definition: color4d.h:61
@ WHITE
Definition: color4d.h:47
@ LIGHTERORANGE
Definition: color4d.h:73
@ LIGHTORANGE
Definition: color4d.h:76
@ BLUE
Definition: color4d.h:55
@ LIGHTGRAY
Definition: color4d.h:46
@ DARKGRAY
Definition: color4d.h:45
@ MAGENTA
Definition: color4d.h:59
@ DARKORANGE
Definition: color4d.h:74
@ DARKMAGENTA
Definition: color4d.h:53
@ LIGHTYELLOW
Definition: color4d.h:48
@ DARKCYAN
Definition: color4d.h:51
@ NBCOLORS
Number of colors.
Definition: color4d.h:78
@ PURERED
Definition: color4d.h:70
@ GREEN
Definition: color4d.h:56
@ CYAN
Definition: color4d.h:57
@ DARKRED
Definition: color4d.h:52
@ DARKBLUE
Definition: color4d.h:49
@ LIGHTCYAN
Definition: color4d.h:63
@ DARKDARKGRAY
Definition: color4d.h:44
@ ORANGE
Definition: color4d.h:75
@ PUREGREEN
Definition: color4d.h:68
@ LIGHTMAGENTA
Definition: color4d.h:65
@ PUREYELLOW
Definition: color4d.h:72
@ YELLOW
Definition: color4d.h:66
@ PUREBLUE
Definition: color4d.h:67
@ LIGHTRED
Definition: color4d.h:64
@ BLACK
Definition: color4d.h:43
@ DARKGREEN
Definition: color4d.h:50
@ PUREMAGENTA
Definition: color4d.h:71
@ RED
Definition: color4d.h:58
@ DARKBROWN
Definition: color4d.h:54
Some functions to handle hotkeys in KiCad.
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:246
bool operator==(const COLOR4D &lhs, const COLOR4D &rhs)
Equality operator, are two colors equal.
Definition: color4d.cpp:248
void from_json(const nlohmann::json &aJson, COLOR4D &aColor)
Definition: color4d.cpp:287
bool operator<(const COLOR4D &lhs, const COLOR4D &rhs)
Definition: color4d.cpp:260
std::ostream & operator<<(std::ostream &aStream, COLOR4D const &aColor)
Syntactic sugar for outputting colors to strings.
Definition: color4d.cpp:275
bool operator!=(const COLOR4D &lhs, const COLOR4D &rhs)
Not equality operator, are two colors not equal.
Definition: color4d.cpp:254
void to_json(nlohmann::json &aJson, const COLOR4D &aColor)
Definition: color4d.cpp:281
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:418
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
unsigned char m_Blue
Definition: color4d.h:85
unsigned char m_Green
Definition: color4d.h:86
unsigned char m_Red
Definition: color4d.h:87
constexpr int delta
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85