more fixes to SVAModifier constructor(s)
[ardour.git] / libs / canvas / colors.cc
index fc1bf474571dd723771ec58206ce1c92106c122b..b66828937e6fea85c7c869c344a7662b8ba55e69 100644 (file)
 */
 
 #include <algorithm>
+#include <sstream>
 #include <cmath>
 #include <stdint.h>
 #include <cfloat>
 
+#include "pbd/convert.h"
+#include "pbd/failed_constructor.h"
+#include "pbd/locale_guard.h"
+
 #include "canvas/colors.h"
 #include "canvas/colorspace.h"
 
@@ -236,6 +241,26 @@ HSV::HSV (Color c)
        color_to_hsva (c, h, s, v, a);
 }
 
+HSV::HSV (const std::string& str)
+{
+       stringstream ss (str);
+       ss >> h;
+       ss >> s;
+       ss >> v;
+       ss >> a;
+}
+
+string
+HSV::to_string () const
+{
+       stringstream ss;
+       ss << h << ' ';
+       ss << s << ' ';
+       ss << v << ' ';
+       ss << a;
+       return ss.str();
+}
+
 bool
 HSV::is_gray () const
 {
@@ -495,3 +520,135 @@ HSV::print (std::ostream& o) const
 
 
 std::ostream& operator<<(std::ostream& o, const ArdourCanvas::HSV& hsv) { hsv.print (o); return o; }
+
+HSV
+HSV::mod (SVAModifier const & svam)
+{
+       return svam (*this);
+}
+
+SVAModifier::SVAModifier (string const &str)
+       : type (Add)
+       , s (0)
+       , v (0)
+       , a (0)
+{
+       from_string (str);
+}
+
+void
+SVAModifier::from_string (string const & str)
+{
+       char op;
+       stringstream ss (str);
+       string mod;
+
+       ss >> op;
+
+       switch (op) {
+       case '*':
+               type = Multiply;
+               /* no-op values for multiply */
+               s = 1.0;
+               v = 1.0;
+               a = 1.0;
+               break;
+       case '+':
+               type = Add;
+               /* no-op values for add */
+               s = 0.0;
+               v = 0.0;
+               a = 1.0;
+               break;
+       case '=':
+               type = Assign;
+               /* this will avoid assignment in operator() (see below) */
+               s = -1.0;
+               v = -1.0;
+               a = -1.0;
+               break;
+       default:
+               throw failed_constructor ();
+       }
+
+       string::size_type pos;
+
+       while (ss) {
+               ss >> mod;
+               if ((pos = mod.find ("alpha:")) != string::npos) {
+                       a = PBD::atof (mod.substr (pos+6));
+               } else if ((pos = mod.find ("saturate:")) != string::npos) {
+                       s = PBD::atof (mod.substr (pos+9));
+               } else if ((pos = mod.find ("darkness:")) != string::npos) {
+                       v = PBD::atof (mod.substr (pos+9));
+               } else {
+                       throw failed_constructor ();
+               }
+       }
+}
+
+string
+SVAModifier::to_string () const
+{
+       PBD::LocaleGuard lg ("POSIX");
+       stringstream ss;
+
+       switch (type) {
+       case Add:
+               ss << '+';
+               break;
+       case Multiply:
+               ss << '*';
+               break;
+       case Assign:
+               ss << '=';
+               break;
+       }
+
+       if (s > -1.0) {
+               ss << " saturate:" << s;
+       }
+
+       if (v > -1.0) {
+               ss << " darker:" << v;
+       }
+
+       if (a > -1.0) {
+               ss << " alpha:" << a;
+       }
+
+       return ss.str();
+}
+
+HSV
+SVAModifier::operator () (HSV& hsv)  const
+{
+       HSV r (hsv);
+       
+       switch (type) {
+       case Add:
+               r.s += s;
+               r.v += v;
+               r.a += a;
+               break;
+       case Multiply:
+               r.s *= s;
+               r.v *= v;
+               r.a *= a;
+               break;
+       case Assign:
+               if (s > -1.0) {
+                       r.s = s;
+               }
+               if (v > -1.0) {
+                       r.v = v;
+               }
+               if (a > -1.0) {
+                       r.a = a;
+               }
+               break;
+       }
+
+       return r;
+}
+