lyx_mirror/src/Color.C

178 lines
2.9 KiB
C++
Raw Normal View History

/**
* \file Color.C
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Angus Leeming
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "Color.h"
#include "LColor.h"
#include <cmath>
#include <sstream>
#include <iomanip>
#ifndef CXX_GLOBAL_CSTD
using std::floor;
#endif
using std::max;
using std::min;
using std::setw;
using std::istringstream;
using std::ostringstream;
using std::string;
namespace lyx {
namespace {
int const nohue = -1;
int hexstrToInt(string const & str)
{
int val = 0;
istringstream is(str);
is >> std::setbase(16) >> val;
return val;
}
} // namespace anon
string const X11hexname(RGBColor const & col)
{
ostringstream ostr;
ostr << '#' << std::setbase(16) << std::setfill('0')
<< setw(2) << col.r
<< setw(2) << col.g
<< setw(2) << col.b;
return ostr.str();
}
RGBColor::RGBColor(string const & x11hexname)
: r(0), g(0), b(0)
{
BOOST_ASSERT(x11hexname.size() == 7 && x11hexname[0] == '#');
r = hexstrToInt(x11hexname.substr(1,2));
g = hexstrToInt(x11hexname.substr(3,2));
b = hexstrToInt(x11hexname.substr(5,2));
}
RGBColor::RGBColor(HSVColor const & hsv)
{
double h = hsv.h;
double const s = hsv.s;
double const v = hsv.v;
double rd, gd, bd;
if (h == nohue || s == 0.0) {
rd = gd = bd = v;
} else {
if (h == 360.0) h = 0.0;
h /= 60.0;
int const j = max(0, static_cast<int>(::floor(h)));
//if (j < 0) j = 0;
double const f = h - j;
double const p = v * (1.0 - s);
double const q = v * (1.0 - (s * f));
double const t = v * (1.0 - (s * (1.0 - f)));
switch (j) {
case 0:
rd = v;
gd = t;
bd = p;
break;
case 1:
rd = q;
gd = v;
bd = p;
break;
case 2:
rd = p;
gd = v;
bd = t;
break;
case 3:
rd = p;
gd = q;
bd = v;
break;
case 4:
rd = t;
gd = p;
bd = v;
break;
case 5:
rd = v;
gd = p;
bd = q;
break;
default:
rd = v;
gd = t;
bd = p;
break; // should never happen.
}
}
r = static_cast<int>(::floor((rd * 255.0) + 0.5));
g = static_cast<int>(::floor((gd * 255.0) + 0.5));
b = static_cast<int>(::floor((bd * 255.0) + 0.5));
}
HSVColor::HSVColor(RGBColor const & rgb)
{
double const r = rgb.r / 255.0;
double const g = rgb.g / 255.0;
double const b = rgb.b / 255.0;
double const maxval = max(max(r, g), b);
double const minval = min(min(r, g), b);
v = maxval;
double const diff = maxval - minval;
if (maxval != 0.0)
s = diff / maxval;
else
s = 0.0;
h = nohue;
if (s != 0.0) {
double const rc = (maxval - r) / diff;
double const gc = (maxval - g) / diff;
double const bc = (maxval - b) / diff;
if (r == maxval)
h = bc - gc;
else if (g == maxval)
h = 2.0 + rc - bc;
else if (b == maxval)
h = 4.0 + gc - rc;
h *= 60.0;
if (h < 0)
h += 360;
}
}
} // namespace lyx