mirror of https://github.com/KLayout/klayout.git
200 lines
4.2 KiB
C++
200 lines
4.2 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2022 Matthias Koefferlein
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
#include "tlColor.h"
|
|
#include "tlString.h"
|
|
#include "tlMath.h"
|
|
|
|
#include <ctype.h>
|
|
#include <algorithm>
|
|
|
|
namespace tl
|
|
{
|
|
|
|
Color::Color ()
|
|
: m_color (0)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
Color::Color (color_t color)
|
|
: m_color (color | 0xff000000)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
Color::Color (unsigned int r, unsigned int g, unsigned int b, unsigned int alpha)
|
|
: m_color ((b & 0xff) | ((g & 0xff) << 8) | ((r & 0xff) << 16) | ((alpha & 0xff) << 24))
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
Color::Color (const std::string &name)
|
|
{
|
|
m_color = 0;
|
|
|
|
tl::Extractor ex (name.c_str ());
|
|
|
|
unsigned int n = 0;
|
|
|
|
ex.test ("#");
|
|
while (! ex.at_end ()) {
|
|
char c = tolower (*ex.get ());
|
|
if (c >= '0' && c <= '9') {
|
|
m_color <<= 4;
|
|
m_color |= (c - '0');
|
|
++n;
|
|
} else if (c >= 'a' && c <= 'f') {
|
|
m_color <<= 4;
|
|
m_color |= (c - 'a') + 10;
|
|
++n;
|
|
}
|
|
++ex;
|
|
}
|
|
|
|
if (n == 0) {
|
|
m_color = 0;
|
|
} else if (n <= 3) {
|
|
m_color = ((m_color & 0xf) * 0x11) | ((m_color & 0xf0) * 0x110) | ((m_color & 0xf00) * 0x1100) | 0xff000000;
|
|
} else if (n <= 4) {
|
|
m_color = ((m_color & 0xf) * 0x11) | ((m_color & 0xf0) * 0x110) | ((m_color & 0xf00) * 0x1100) | ((m_color & 0xf000) * 0x11000);
|
|
} else if (n <= 6) {
|
|
m_color |= 0xff000000;
|
|
}
|
|
}
|
|
|
|
std::string
|
|
Color::to_string () const
|
|
{
|
|
if (! is_valid ()) {
|
|
|
|
return std::string ();
|
|
|
|
} else {
|
|
|
|
unsigned int n = 8;
|
|
if ((m_color & 0xff000000) == 0xff000000) {
|
|
n = 6;
|
|
}
|
|
|
|
uint32_t c = m_color;
|
|
char s [10];
|
|
s[n + 1] = 0;
|
|
s[0] = '#';
|
|
while (n > 0) {
|
|
s [n] = "0123456789abcdef" [c & 0xf];
|
|
c >>= 4;
|
|
--n;
|
|
}
|
|
|
|
return std::string (s);
|
|
|
|
}
|
|
}
|
|
|
|
bool
|
|
Color::is_valid () const
|
|
{
|
|
return (m_color & 0xff000000) != 0;
|
|
}
|
|
|
|
void
|
|
Color::get_hsv (unsigned int &hue, unsigned int &saturation, unsigned int &value) const
|
|
{
|
|
double r = double (red ()) / 255.0;
|
|
double g = double (green ()) / 255.0;
|
|
double b = double (blue ()) / 255.0;
|
|
|
|
double max = std::max (r, std::max (g, b));
|
|
double min = std::min (r, std::min (g, b));
|
|
double delta = max - min;
|
|
|
|
value = (unsigned int) tl::round (255.0 * max, 1);
|
|
hue = 0;
|
|
saturation = 0;
|
|
|
|
if (! tl::equal (delta, 0.0)) {
|
|
|
|
saturation = (unsigned int) tl::round (255.0 * delta / max, 1);
|
|
double h = 0.0;
|
|
if (tl::equal (r, max)) {
|
|
h = (g - b) / delta;
|
|
} else if (tl::equal (g, max)) {
|
|
h = 2.0f + (b - r) / delta;
|
|
} else if (tl::equal (b, max)) {
|
|
h = 4.0f + (r - g) / delta;
|
|
}
|
|
h *= 60.0;
|
|
if (tl::less (h, 0.0)) {
|
|
h += 360.0;
|
|
}
|
|
|
|
hue = (unsigned int) tl::round (h, 1);
|
|
|
|
}
|
|
}
|
|
|
|
static tl::Color color_d (double r, double g, double b)
|
|
{
|
|
return tl::Color (tl::round (r * 255.0, 1), tl::round (g * 255.0, 1), tl::round (b * 255.0, 1));
|
|
}
|
|
|
|
tl::Color
|
|
Color::from_hsv (unsigned int hue, unsigned int saturation, unsigned int value)
|
|
{
|
|
if (saturation == 0) {
|
|
return tl::Color (value, value, value);
|
|
}
|
|
|
|
hue = (hue + 360) % 360;
|
|
|
|
double h = double (hue) / 60.0;
|
|
double s = double (saturation) / 255.0;
|
|
double v = double (value) / 255.0;
|
|
|
|
int i = int (tl::round_down (h, 1));
|
|
double f = (i & 1) != 0 ? h - i : 1.0 - h + i;
|
|
double p = v * (1.0 - s);
|
|
double q = v * (1.0 - s * f);
|
|
|
|
switch (i) {
|
|
case 0:
|
|
return color_d (v, q, p);
|
|
case 1:
|
|
return color_d (q, v, p);
|
|
case 2:
|
|
return color_d (p, v, q);
|
|
case 3:
|
|
return color_d (p, q, v);
|
|
case 4:
|
|
return color_d (q, p, v);
|
|
case 5:
|
|
return color_d (v, p, q);
|
|
default:
|
|
return tl::Color ();
|
|
}
|
|
|
|
}
|
|
|
|
}
|