]> git.lyx.org Git - features.git/blobdiff - src/Color.cpp
I guess Windows folks are not too happy with files named color.h and Color.h
[features.git] / src / Color.cpp
index 125321c1de1ca6937a2c8dabf61c9a67dd7f3613..3474850fbcac8772a6861fa8d842ea4cae57c1ef 100644 (file)
 #include "support/lstrings.h"
 
 #include <map>
+#include <cmath>
+#include <sstream>
+#include <iomanip>
 
 
-namespace lyx {
+#ifndef CXX_GLOBAL_CSTD
+using std::floor;
+#endif
 
-using support::compare_ascii_no_case;
-using support::ascii_lowercase;
+using std::max;
+using std::min;
+using std::setw;
 
-using std::endl;
+using std::istringstream;
+using std::ostringstream;
 using std::string;
+using std::endl;
+
+using lyx::support::compare_ascii_no_case;
+using lyx::support::ascii_lowercase;
 
 
 namespace {
 
 struct ColorEntry {
-       Color::color lcolor;
+       lyx::Color::color lcolor;
        char const * guiname;
        char const * latexname;
        char const * x11name;
        char const * lyxname;
 };
 
+int const nohue = -1;
+
+int hexstrToInt(string const & str)
+{
+       int val = 0;
+       istringstream is(str);
+       is >> std::setbase(16) >> val;
+       return val;
+}
+
+} // namespace anon
+
+
+
+namespace lyx {
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// RGBColor
+//
+/////////////////////////////////////////////////////////////////////
+
+
+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::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;
+       }
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// Color::Pimpl
+//
+/////////////////////////////////////////////////////////////////////
+
 class Color::Pimpl {
 public:
        ///