27#include <nlohmann/json.hpp>
36#define TS( string ) wxString( _HKI( string ) ).ToStdString()
86 if( aColor <= UNSPECIFIED_COLOR || aColor >=
NBCOLORS )
94 for( ; candidate <
NBCOLORS; ++candidate )
96 if(
colorRefs()[candidate].m_Numcolor == aColor )
122 r = aColor.Red() / 255.0;
123 g = aColor.Green() / 255.0;
124 b = aColor.Blue() / 255.0;
125 a = aColor.Alpha() / 255.0;
133 if( c.Set( aColorString ) )
136 g = c.Green() / 255.0;
137 b = c.Blue() / 255.0;
138 a = c.Alpha() / 255.0;
152 const int red = c.Red();
153 const int green = c.Green();
154 const int blue = c.Blue();
155 const int alpha = c.Alpha();
157 if ( alpha == wxALPHA_OPAQUE )
159 str.Printf( wxT(
"rgb(%d, %d, %d)" ),
red, green, blue );
163 wxString alpha_str = wxString::FromCDouble( alpha / 255.0, 3 );
168 alpha_str.Replace( wxT(
"," ), wxT(
"." ) );
170 str.Printf( wxT(
"rgba(%d, %d, %d, %s)" ),
red, green, blue, alpha_str );
179 wxString str = aColorString;
183 if( str.length() < 7 || !str.StartsWith(
'#' ) )
188 if( wxSscanf( str.wx_str() + 1, wxT(
"%lx" ), &tmp ) != 1 )
191 if( str.length() >= 9 )
193 r = ( (tmp >> 24) & 0xFF ) / 255.0;
194 g = ( (tmp >> 16) & 0xFF ) / 255.0;
195 b = ( (tmp >> 8) & 0xFF ) / 255.0;
196 a = ( tmp & 0xFF ) / 255.0;
200 r = ( (tmp >> 16) & 0xFF ) / 255.0;
201 g = ( (tmp >> 8) & 0xFF ) / 255.0;
202 b = ( tmp & 0xFF ) / 255.0;
212 return wxString::Format( wxT(
"#%02X%02X%02X%02X" ),
222 using CHAN_T = wxColourBase::ChannelType;
224 const wxColour colour(
225 static_cast<CHAN_T
>(
r * 255 + 0.5 ),
static_cast<CHAN_T
>(
g * 255 + 0.5 ),
226 static_cast<CHAN_T
>(
b * 255 + 0.5 ),
static_cast<CHAN_T
>(
a * 255 + 0.5 ) );
236 candidate.
r = ( (unsigned) ( 255.0 *
r ) | (unsigned) ( 255.0 * aColor.
r ) ) / 255.0,
237 candidate.
g = ( (
unsigned) ( 255.0 *
g ) | (
unsigned) ( 255.0 * aColor.
g ) ) / 255.0,
238 candidate.
b = ( (unsigned) ( 255.0 *
b ) | (unsigned) ( 255.0 * aColor.
b ) ) / 255.0,
241 candidate.
a = ( aColor.
a +
a ) / 2;
251 return lhs.
a == rhs.
a && lhs.
r == rhs.
r && lhs.
g == rhs.
g && lhs.
b == rhs.
b;
257 return !( lhs == rhs );
265 else if( lhs.
g < rhs.
g )
267 else if( lhs.
b < rhs.
b )
269 else if( lhs.
a < rhs.
a )
284 aJson = nlohmann::json( aColor.
ToCSSString().ToStdString() );
296void COLOR4D::ToHSL(
double& aOutHue,
double& aOutSaturation,
double& aOutLightness )
const
298 auto min = std::min(
r, std::min(
g,
b ) );
299 auto max = std::max(
r, std::max(
g,
b ) );
300 auto diff = max - min;
302 aOutLightness = ( max + min ) / 2.0;
304 if( aOutLightness >= 1.0 )
305 aOutSaturation = 0.0;
307 aOutSaturation = diff / ( 1.0 -
std::abs( 2.0 * aOutLightness - 1.0 ) );
314 hue = (
g -
b ) / diff;
316 hue = (
b -
r ) / diff + 2.0;
318 hue = (
r -
g ) / diff + 4.0;
320 aOutHue = hue > 0.0 ? hue * 60.0 : hue * 60.0 + 360.0;
322 while( aOutHue < 0.0 )
329 const auto P = ( 1.0 -
std::abs( 2.0 * aInLightness - 1.0 ) ) * aInSaturation;
330 const auto scaled_hue = aInHue / 60.0;
331 const auto Q = P * ( 1.0 -
std::abs( std::fmod( scaled_hue, 2.0 ) - 1.0 ) );
333 r =
g =
b = aInLightness - P / 2.0;
335 if (scaled_hue < 1.0)
340 else if (scaled_hue < 2.0)
345 else if (scaled_hue < 3.0)
350 else if (scaled_hue < 4.0)
355 else if (scaled_hue < 5.0)
369 bool aAlwaysDefineHue )
const
371 double min, max,
delta;
374 min = min <
b ? min :
b;
377 max = max >
b ? max :
b;
384 aOutSaturation = (
delta / max );
388 aOutSaturation = 0.0;
389 aOutHue = aAlwaysDefineHue ? 0.0 : NAN;
406 aOutHue = 2.0 + (
b -
r ) /
delta;
408 aOutHue = 4.0 + (
r -
g ) /
delta;
417 aOutHue = aAlwaysDefineHue ? 0.0 : NAN;
450 double p = aInV * ( 1.0 - aInS );
451 double q = aInV * ( 1.0 - ( aInS * ff ) );
452 double t = aInV * ( 1.0 - ( aInS * ( 1.0 - ff ) ) );
499 if(
r ==
g &&
r ==
b )
504 ToHSV( h, s, v,
true );
514 if(
r ==
g &&
r ==
b )
534 return (
r - other.
r ) * (
r - other.
r )
535 + (
g - other.
g ) * (
g - other.
g )
536 + (
b - other.
b ) * (
b - other.
b );
555 int nearest_distance = 255 * 255 * 3 + 1;
557 for(
EDA_COLOR_T trying = EDA_COLOR_T::BLACK; trying < EDA_COLOR_T::NBCOLORS;
558 trying =
static_cast<EDA_COLOR_T>( int( trying ) + 1 ) )
565 if( distance < nearest_distance && c.m_Red >= aR &&
579 r = std::clamp( aRed, 0, 255 ) / 255.0;
580 g = std::clamp( aGreen, 0, 255 ) / 255.0;
581 b = std::clamp( aBlue, 0, 255 ) / 255.0;
582 a = std::clamp( aAlpha, 0.0, 1.0 );
591 return (
r < aRhs.
r ) ? -1 : 1;
594 return (
g < aRhs.
g ) ? -1 : 1;
597 return (
b < aRhs.
b ) ? -1 : 1;
600 return (
a < aRhs.
a ) ? -1 : 1;
609 double cr = (
r <= 0.04045 ) ? (
r / 12.92 ) : std::pow( (
r + 0.055 ) / 1.055, 2.4 );
610 double cg = (
g <= 0.04045 ) ? (
g / 12.92 ) : std::pow( (
g + 0.055 ) / 1.055, 2.4 );
611 double cb = (
b <= 0.04045 ) ? (
b / 12.92 ) : std::pow( (
b + 0.055 ) / 1.055, 2.4 );
613 return 0.2126 * cr + 0.7152 * cg + 0.0722 * cb;
624 return ( aRL + 0.05 ) / ( bRL + 0.05 );
626 return ( bRL + 0.05 ) / ( aRL + 0.05 );
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
A color representation with 4 components: red, green, blue, alpha.
static const COLOR4D CLEAR
void ToHSV(double &aOutHue, double &aOutSaturation, double &aOutValue, bool aAlwaysDefineHue=false) const
Convert current color (stored in RGB) to HSV format.
static double ContrastRatio(const COLOR4D &aLeft, const COLOR4D &aRight)
Compute the contrast ration between two colors using the formula from WCAG21.
void ToHSL(double &aOutHue, double &aOutSaturation, double &aOutLightness) const
Converts current color (stored in RGB) to HSL format.
bool SetFromWxString(const wxString &aColorString)
Set color values by parsing a string using wxColour::Set().
bool SetFromHexString(const wxString &aColorString)
COLOR4D LegacyMix(const COLOR4D &aColor) const
Mix this COLOR4D with an input COLOR4D using the OR-mixing of legacy canvas.
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.
void FromHSV(double aInH, double aInS, double aInV)
Changes currently used color to the one given by hue, saturation and value parameters.
wxString ToHexString() const
wxString ToCSSString() const
int Compare(const COLOR4D &aRhs) const
static const COLOR4D WHITE
double RelativeLuminance() const
Compute the relative luminance of a color using the formula from WCAG21.
wxColour ToColour() const
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
COLOR4D & Desaturate()
Removes color (in HSL model)
double Distance(const COLOR4D &other) const
Returns the distance (in RGB space) between two colors.
void FromHSL(double aInHue, double aInSaturation, double aInLightness)
Change currently used color to the one given by hue, saturation and lightness parameters.
static const COLOR4D BLACK
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.
COLOR4D & Saturate(double aFactor)
Saturates the color to a given factor (in HSV model)
const StructColors * colorRefs()
Global list of legacy color names, still used all over the place for constructing COLOR4D's.
EDA_COLOR_T
Legacy color enumeration.
@ NBCOLORS
Number of colors.
std::ostream & operator<<(std::ostream &aStream, const EDA_TEXT &aText)
Some functions to handle hotkeys in KiCad.
The Cairo implementation of the graphics abstraction layer.
void from_json(const nlohmann::json &aJson, COLOR4D &aColor)
bool operator==(const COLOR4D &lhs, const COLOR4D &rhs)
Equality operator, are two colors equal.
void to_json(nlohmann::json &aJson, const COLOR4D &aColor)
bool operator<(const COLOR4D &lhs, const COLOR4D &rhs)
bool operator!=(const COLOR4D &lhs, const COLOR4D &rhs)
Not equality operator, are two colors not equal.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)