Code

Initial support for icc color selection including CMYK
authorjoncruz <joncruz@users.sourceforge.net>
Tue, 25 Sep 2007 02:54:32 +0000 (02:54 +0000)
committerjoncruz <joncruz@users.sourceforge.net>
Tue, 25 Sep 2007 02:54:32 +0000 (02:54 +0000)
15 files changed:
src/color.cpp
src/color.h
src/desktop-style.cpp
src/dialogs/fill-style.cpp
src/dialogs/stroke-style.cpp
src/style.cpp
src/style.h
src/widgets/Makefile_insert
src/widgets/paint-selector.cpp
src/widgets/sp-color-gtkselector.cpp
src/widgets/sp-color-icc-selector.cpp [new file with mode: 0644]
src/widgets/sp-color-icc-selector.h [new file with mode: 0644]
src/widgets/sp-color-notebook.cpp
src/widgets/sp-color-selector.cpp
src/widgets/sp-color-slider.cpp

index 8dc4c865762af724607a92ef5149ffabed55e004..6b2281f2697457dde841dd58e3dc5391f7df25aa 100644 (file)
 #include <math.h>
 #include "color.h"
 #include "svg/svg-icc-color.h"
+#include "svg/svg-color.h"
+
+#include "svg/css-ostringstream.h"
+
+using Inkscape::CSSOStringStream;
+using std::vector;
 
 static bool profileMatches( SVGICCColor const* first, SVGICCColor const* second );
 
@@ -96,8 +102,7 @@ bool SPColor::isClose( SPColor const& other, float epsilon ) const
         && (fabs((v.c[1]) - (other.v.c[1])) < epsilon)
         && (fabs((v.c[2]) - (other.v.c[2])) < epsilon);
 
-    // TODO uncomment once we start using that profile.  Will be RSN
-    //match &= profileMatches( icc, other.icc );
+    match &= profileMatches( icc, other.icc );
 
     return match;
 }
@@ -176,6 +181,31 @@ guint32 SPColor::toRGBA32( gdouble alpha ) const
     return toRGBA32( static_cast<gint>(SP_COLOR_F_TO_U(alpha)) );
 }
 
+std::string SPColor::toString() const
+{
+    CSSOStringStream css;
+
+    std::string result;
+    char tmp[64] = {0};
+
+    sp_svg_write_color(tmp, sizeof(tmp), toRGBA32(0x0ff));
+    css << tmp;
+
+    if ( !css.str().empty() ) {
+        css << " ";
+    }
+    css << "icc-color(" << icc->colorProfile;
+    for (vector<double>::const_iterator i(icc->colors.begin()),
+             iEnd(icc->colors.end());
+         i != iEnd; ++i) {
+        css << ", " << *i;
+    }
+    css << ')';
+
+    return css.str();
+}
+
+
 /**
  * Fill rgb float array with values from SPColor.
  * \pre color != NULL && rgb != NULL && rgb[0-2] is meaningful
index e9394360900841a8c4199c9d62679fcad763e381..4fcffad8e121e8eeaeeb30e5d7fb7b7755ff3e88 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <gdk/gdktypes.h>
+#include <string>
 
 /* Useful composition macros */
 
@@ -55,6 +56,8 @@ struct SPColor {
     guint32 toRGBA32( gint alpha ) const;
     guint32 toRGBA32( gdouble alpha ) const;
 
+    std::string toString() const;
+
     SVGICCColor* icc;
     union {
         float c[3];
index b1dca7f17e209a7faa8a4f668812c6c6610c4b52..236130173fec7f4536e6429f23c2f540ddcd920a 100644 (file)
@@ -40,6 +40,7 @@
 #include "sp-path.h"
 
 #include "desktop-style.h"
+#include "svg/svg-icc-color.h"
 
 /**
  * Set color on selection on desktop.
@@ -55,7 +56,7 @@ sp_desktop_set_color(SPDesktop *desktop, ColorRGBA const &color, bool is_relativ
 
     guint32 rgba = SP_RGBA32_F_COMPOSE(color[0], color[1], color[2], color[3]);
     gchar b[64];
-    sp_svg_write_color(b, 64, rgba);
+    sp_svg_write_color(b, sizeof(b), rgba);
     SPCSSAttr *css = sp_repr_css_attr_new();
     if (fill) {
         sp_repr_css_set_property(css, "fill", b);
@@ -424,6 +425,8 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill
     bool paintImpossible = true;
     paint_res->set = TRUE;
 
+    SVGICCColor* iccColor = 0;
+    bool iccSeen = false;
     gfloat c[4];
     c[0] = c[1] = c[2] = c[3] = 0.0;
     gint num = 0;
@@ -502,9 +505,17 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill
                 prev[1] = d[1];
                 prev[2] = d[2];
                 paint_res->setColor(d[0], d[1], d[2]);
+                iccColor = paint->value.color.icc;
+                iccSeen = true;
             } else {
                 if (same_color && (prev[0] != d[0] || prev[1] != d[1] || prev[2] != d[2]))
                     same_color = false;
+                if ( iccSeen ) {
+                    if(paint->value.color.icc) {
+                        // TODO fix this
+                        iccColor = 0;
+                    }
+                }
             }
 
             // average color
@@ -543,6 +554,14 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill
         } else {
             style_res->stroke_opacity.value = SP_SCALE24_FROM_FLOAT (c[3]);
         }
+
+
+        if ( iccSeen && iccColor ) {
+            // TODO check for existing
+            SVGICCColor* tmp = new SVGICCColor(*iccColor);
+            paint_res->value.color.icc = tmp;
+        }
+
         if (num > 1) {
             if (same_color)
                 return QUERY_STYLE_MULTIPLE_SAME;
index 1dfaea5461b132052b085d0d9161babac0bba0d9..3c0620feb47af8e341b601a168a5e45c06278b00 100644 (file)
@@ -211,11 +211,7 @@ sp_fill_style_widget_update (SPWidget *spw)
                                      SP_PAINT_SELECTOR_FILLRULE_NONZERO : SP_PAINT_SELECTOR_FILLRULE_EVENODD);
 
             if (query->fill.set && query->fill.isColor()) {
-                gfloat d[3];
-                sp_color_get_rgb_floatv (&query->fill.value.color, d);
-                SPColor color( d[0], d[1], d[2] );
-                sp_paint_selector_set_color_alpha (psel, &color, SP_SCALE24_TO_FLOAT (query->fill_opacity.value));
-
+                sp_paint_selector_set_color_alpha (psel, &query->fill.value.color, SP_SCALE24_TO_FLOAT (query->fill_opacity.value));
             } else if (query->fill.set && query->fill.isPaintserver()) {
 
                 SPPaintServer *server = SP_STYLE_FILL_SERVER (query);
index 9dc7131fcb15843bc3d775fa28e57aaf9d1184d0..08f3d90317fd5c8c76966f0de65041c8fb059510 100644 (file)
@@ -248,10 +248,7 @@ sp_stroke_style_paint_update (SPWidget *spw)
                     sp_update_pattern_list (psel, pat);
                 }
             } else if (query->stroke.set && query->stroke.isColor()) {
-                gfloat d[3];
-                sp_color_get_rgb_floatv (&query->stroke.value.color, d);
-                SPColor color( d[0], d[1], d[2] );
-                sp_paint_selector_set_color_alpha (psel, &color, SP_SCALE24_TO_FLOAT (query->stroke_opacity.value));
+                sp_paint_selector_set_color_alpha (psel, &query->stroke.value.color, SP_SCALE24_TO_FLOAT (query->stroke_opacity.value));
 
             }
             break;
index b817ce083b72bb0f32f0dece1530d12cf65d78ce..e0cd1e947d07e7c678f7760dfd5c1097cbabf67b 100644 (file)
@@ -3030,7 +3030,7 @@ sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume
                         delete tmp;
                         tmp = 0;
                     }
-                    paint->value.iccColor = tmp;
+                    paint->value.color.icc = tmp;
                 }
             }
         }
@@ -3522,10 +3522,10 @@ sp_paint_differ(SPIPaint const *const a, SPIPaint const *const b)
 
     if ( a->isColor() ) {
         return !( (a->value.color == b->value.color)
-                 && ((a->value.iccColor == b->value.iccColor)
-                     || (a->value.iccColor && b->value.iccColor
-                         && (a->value.iccColor->colorProfile == b->value.iccColor->colorProfile)
-                         && (a->value.iccColor->colors == b->value.iccColor->colors))));
+                 && ((a->value.color.icc == b->value.color.icc)
+                     || (a->value.color.icc && b->value.color.icc
+                         && (a->value.color.icc->colorProfile == b->value.color.icc->colorProfile)
+                         && (a->value.color.icc->colors == b->value.color.icc->colors))));
     /* todo: Allow for epsilon differences in iccColor->colors, e.g. changes small enough not to show up
      * in the string representation. */
     }
@@ -3582,13 +3582,13 @@ sp_style_write_ipaint(gchar *b, gint const len, gchar const *const key,
                 css << color_buf;
             }
 
-            if (paint->value.iccColor) {
+            if (paint->value.color.icc) {
                 if ( !css.str().empty() ) {
                     css << " ";
                 }
-                css << "icc-color(" << paint->value.iccColor->colorProfile;
-                for (vector<double>::const_iterator i(paint->value.iccColor->colors.begin()),
-                         iEnd(paint->value.iccColor->colors.end());
+                css << "icc-color(" << paint->value.color.icc->colorProfile;
+                for (vector<double>::const_iterator i(paint->value.color.icc->colors.begin()),
+                         iEnd(paint->value.color.icc->colors.end());
                      i != iEnd; ++i) {
                     css << ", " << *i;
                 }
@@ -3696,9 +3696,6 @@ void SPIPaint::clear()
     {
         value.href->detach();
     }
-
-    delete value.iccColor;
-    value.iccColor = 0;
 }
 
 
index 9b2d2878ae631456600b5baa1e263289906517fa..6e62187bc1f431184de1d9bd1b25a6de894a86d0 100644 (file)
@@ -156,7 +156,6 @@ struct SPIPaint {
     struct {
          SPPaintServerReference *href;
          SPColor color;
-         SVGICCColor *iccColor;
     } value;
 
 
index 854ca9122709f7a41c32c173fa30326b96cd04cc..d460371579a0a152ecc004f999adb2497bedc2b8 100644 (file)
@@ -41,6 +41,8 @@ widgets_libspwidgets_a_SOURCES =      \
        widgets/shrink-wrap-button.h    \
        widgets/sp-color-gtkselector.cpp        \
        widgets/sp-color-gtkselector.h  \
+       widgets/sp-color-icc-selector.cpp       \
+       widgets/sp-color-icc-selector.h \
        widgets/sp-color-notebook.cpp   \
        widgets/sp-color-notebook.h     \
        widgets/sp-color-preview.cpp    \
index 3c103afb00c7280d735d019e6e6dfbf2b10fb947..56daf948d3fc8c3dff322611abec8eb7d8358f8e 100644 (file)
 
 #include "paint-selector.h"
 
+#ifdef SP_PS_VERBOSE
+#include "svg/svg-icc-color.h"
+#endif // SP_PS_VERBOSE
+
 enum {
     MODE_CHANGED,
     GRABBED,
@@ -556,18 +560,21 @@ sp_paint_selector_set_mode_none(SPPaintSelector *psel)
 static void
 sp_paint_selector_color_grabbed(SPColorSelector *csel, SPPaintSelector *psel)
 {
+    (void)csel;
     gtk_signal_emit(GTK_OBJECT(psel), psel_signals[GRABBED]);
 }
 
 static void
 sp_paint_selector_color_dragged(SPColorSelector *csel, SPPaintSelector *psel)
 {
+    (void)csel;
     gtk_signal_emit(GTK_OBJECT(psel), psel_signals[DRAGGED]);
 }
 
 static void
 sp_paint_selector_color_released(SPColorSelector *csel, SPPaintSelector *psel)
 {
+    (void)csel;
     gtk_signal_emit(GTK_OBJECT(psel), psel_signals[RELEASED]);
 }
 
@@ -582,6 +589,7 @@ sp_paint_selector_color_changed(SPColorSelector *csel, SPPaintSelector *psel)
 static void
 sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelectorMode mode)
 {
+    (void)mode;
     GtkWidget *csel;
 
     sp_paint_selector_set_style_buttons(psel, psel->solid);
@@ -627,24 +635,28 @@ sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelectorMode mode
 static void
 sp_paint_selector_gradient_grabbed(SPColorSelector *csel, SPPaintSelector *psel)
 {
+    (void)csel;
     gtk_signal_emit(GTK_OBJECT(psel), psel_signals[GRABBED]);
 }
 
 static void
 sp_paint_selector_gradient_dragged(SPColorSelector *csel, SPPaintSelector *psel)
 {
+    (void)csel;
     gtk_signal_emit(GTK_OBJECT(psel), psel_signals[DRAGGED]);
 }
 
 static void
 sp_paint_selector_gradient_released(SPColorSelector *csel, SPPaintSelector *psel)
 {
+    (void)csel;
     gtk_signal_emit(GTK_OBJECT(psel), psel_signals[RELEASED]);
 }
 
 static void
 sp_paint_selector_gradient_changed(SPColorSelector *csel, SPPaintSelector *psel)
 {
+    (void)csel;
     gtk_signal_emit(GTK_OBJECT(psel), psel_signals[CHANGED]);
 }
 
@@ -707,6 +719,7 @@ sp_paint_selector_set_style_buttons(SPPaintSelector *psel, GtkWidget *active)
 static void
 sp_psel_pattern_destroy(GtkWidget *widget,  SPPaintSelector *psel)
 {
+    (void)psel;
     // drop our reference to the pattern menu widget
     g_object_unref( G_OBJECT(widget) );
 }
@@ -714,6 +727,7 @@ sp_psel_pattern_destroy(GtkWidget *widget,  SPPaintSelector *psel)
 static void
 sp_psel_pattern_change(GtkWidget *widget,  SPPaintSelector *psel)
 {
+    (void)widget;
     gtk_signal_emit(GTK_OBJECT(psel), psel_signals[CHANGED]);
 }
 
@@ -904,12 +918,18 @@ sp_paint_selector_set_flat_color(SPPaintSelector *psel, SPDesktop *desktop, gcha
     SPColor color;
     gfloat alpha;
     sp_paint_selector_get_color_alpha(psel, &color, &alpha);
-    guint32 rgba = color.toRGBA32( alpha );
 
-    gchar b[64];
-    sp_svg_write_color(b, 64, rgba);
+    std::string colorStr = color.toString();
+
+#ifdef SP_PS_VERBOSE
+    guint32 rgba = color.toRGBA32( alpha );
+    g_message("sp_paint_selector_set_flat_color() to '%s' from 0x%08x::%s",
+              colorStr.c_str(),
+              rgba,
+              (color.icc?color.icc->colorProfile.c_str():"<null>") );
+#endif // SP_PS_VERBOSE
 
-    sp_repr_css_set_property(css, color_property, b);
+    sp_repr_css_set_property(css, color_property, colorStr.c_str());
     Inkscape::CSSOStringStream osalpha;
     osalpha << alpha;
     sp_repr_css_set_property(css, opacity_property, osalpha.str().c_str());
@@ -926,7 +946,7 @@ sp_style_determine_paint_selector_mode(SPStyle *style, bool isfill)
     SPIPaint& target = isfill ? style->fill : style->stroke;
 
     if ( !target.set ) {
-        SPPaintSelectorMode mode = SP_PAINT_SELECTOR_MODE_UNSET;
+        mode = SP_PAINT_SELECTOR_MODE_UNSET;
     } else if ( target.isPaintserver() ) {
         SPPaintServer *server = isfill? SP_STYLE_FILL_SERVER(style) : SP_STYLE_STROKE_SERVER(style);
 
index b583903e3e4757f9c627f6f1d5bf052bef35fe9f..9a16ab05962cf4e01d8b518267bee0a6d3f6b934 100644 (file)
@@ -131,7 +131,6 @@ ColorGtkselector::~ColorGtkselector()
 void ColorGtkselector::_colorChanged( const SPColor& color, gfloat alpha )
 {
     GdkColor gcolor;
-    float rgb[3];
     g_return_if_fail (_csel != NULL);
     g_return_if_fail (SP_IS_COLOR_GTKSELECTOR (_csel));
     g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
@@ -139,11 +138,10 @@ void ColorGtkselector::_colorChanged( const SPColor& color, gfloat alpha )
     _color = color;
     _alpha = alpha;
 
-    sp_color_get_rgb_floatv( &color, rgb );
     gcolor.pixel = 0;
-    gcolor.red   = static_cast< guint16 > (rgb[0] * 65535);
-    gcolor.green = static_cast< guint16 > (rgb[1] * 65535);
-    gcolor.blue  = static_cast< guint16 > (rgb[2] * 65535);
+    gcolor.red   = static_cast< guint16 > (color.v.c[0] * 65535);
+    gcolor.green = static_cast< guint16 > (color.v.c[1] * 65535);
+    gcolor.blue  = static_cast< guint16 > (color.v.c[2] * 65535);
 
 //     g_message( "*****  _colorChanged %04x %04x %04x", gcolor.red, gcolor.green, gcolor.blue );
     g_signal_handler_block( _gtkThing, _sigId );
diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp
new file mode 100644 (file)
index 0000000..23294d6
--- /dev/null
@@ -0,0 +1,776 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <math.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtkspinbutton.h>
+#include <glibmm/i18n.h>
+#include "../dialogs/dialog-events.h"
+#include "sp-color-icc-selector.h"
+#include "sp-color-scales.h"
+#include "svg/svg-icc-color.h"
+#include "inkscape.h"
+
+#define noDEBUG_LCMS
+
+#if ENABLE_LCMS
+#include "color-profile-fns.h"
+#include "color-profile.h"
+//#define DEBUG_LCMS
+#ifdef DEBUG_LCMS
+#include "prefs-utils.h"
+#include <gtk/gtkmessagedialog.h>
+#endif // DEBUG_LCMS
+#endif // ENABLE_LCMS
+
+
+#ifdef DEBUG_LCMS
+extern guint update_in_progress;
+#define DEBUG_MESSAGE(key, ...) \
+{\
+    gint dump = prefs_get_int_attribute_limited("options.scislac", #key, 0, 0, 1);\
+    gint dumpD = prefs_get_int_attribute_limited("options.scislac", #key"D", 0, 0, 1);\
+    gint dumpD2 = prefs_get_int_attribute_limited("options.scislac", #key"D2", 0, 0, 1);\
+    dumpD &= ( (update_in_progress == 0) || dumpD2 );\
+    if ( dump )\
+    {\
+        g_message( __VA_ARGS__ );\
+\
+    }\
+    if ( dumpD )\
+    {\
+        GtkWidget *dialog = gtk_message_dialog_new(NULL,\
+                                                   GTK_DIALOG_DESTROY_WITH_PARENT, \
+                                                   GTK_MESSAGE_INFO,    \
+                                                   GTK_BUTTONS_OK,      \
+                                                   __VA_ARGS__          \
+                                                   );\
+        g_signal_connect_swapped(dialog, "response",\
+                                 G_CALLBACK(gtk_widget_destroy),        \
+                                 dialog);                               \
+        gtk_widget_show_all( dialog );\
+    }\
+}
+#endif // DEBUG_LCMS
+
+
+
+G_BEGIN_DECLS
+
+static void sp_color_icc_selector_class_init (SPColorICCSelectorClass *klass);
+static void sp_color_icc_selector_init (SPColorICCSelector *cs);
+static void sp_color_icc_selector_destroy (GtkObject *object);
+
+static void sp_color_icc_selector_show_all (GtkWidget *widget);
+static void sp_color_icc_selector_hide_all (GtkWidget *widget);
+
+
+G_END_DECLS
+
+static SPColorSelectorClass *parent_class;
+
+#define XPAD 4
+#define YPAD 1
+
+GType
+sp_color_icc_selector_get_type (void)
+{
+    static GType type = 0;
+    if (!type) {
+        static const GTypeInfo info = {
+            sizeof (SPColorICCSelectorClass),
+            NULL, /* base_init */
+            NULL, /* base_finalize */
+            (GClassInitFunc) sp_color_icc_selector_class_init,
+            NULL, /* class_finalize */
+            NULL, /* class_data */
+            sizeof (SPColorICCSelector),
+            0,    /* n_preallocs */
+            (GInstanceInitFunc) sp_color_icc_selector_init,
+            0,    /* value_table */
+        };
+
+        type = g_type_register_static (SP_TYPE_COLOR_SELECTOR,
+                                       "SPColorICCSelector",
+                                       &info,
+                                       static_cast< GTypeFlags > (0) );
+    }
+    return type;
+}
+
+static void
+sp_color_icc_selector_class_init (SPColorICCSelectorClass *klass)
+{
+    static const gchar* nameset[] = {N_("CMS"), 0};
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+    SPColorSelectorClass *selector_class;
+
+    object_class = (GtkObjectClass *) klass;
+    widget_class = (GtkWidgetClass *) klass;
+    selector_class = SP_COLOR_SELECTOR_CLASS (klass);
+
+    parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass));
+
+    selector_class->name = nameset;
+    selector_class->submode_count = 1;
+
+    object_class->destroy = sp_color_icc_selector_destroy;
+
+    widget_class->show_all = sp_color_icc_selector_show_all;
+    widget_class->hide_all = sp_color_icc_selector_hide_all;
+}
+
+ColorICCSelector::ColorICCSelector( SPColorSelector* csel )
+    : ColorSelector( csel ),
+      _updating( FALSE ),
+      _dragging( FALSE ),
+      _fooCount(0),
+      _fooScales(0),
+      _fooAdj(0),
+      _fooSlider(0),
+      _fooBtn(0),
+      _fooLabel(0),
+      _fooMap(0),
+      _adj(0),
+      _sbtn(0),
+      _label(0),
+      _tt(0)
+#if ENABLE_LCMS
+    ,
+      _profileName(""),
+      _profIntent(Inkscape::RENDERING_INTENT_UNKNOWN),
+      _profileSpace(icSigRgbData),
+      _profileClass(icSigInputClass),
+      _prof(0),
+      _destProf(0),
+      _transf(0),
+      _profChannelCount(0)
+#endif // ENABLE_LCMS
+{
+}
+
+ColorICCSelector::~ColorICCSelector()
+{
+    _adj = 0;
+    _sbtn = 0;
+    _label = 0;
+}
+
+void sp_color_icc_selector_init (SPColorICCSelector *cs)
+{
+    SP_COLOR_SELECTOR(cs)->base = new ColorICCSelector( SP_COLOR_SELECTOR(cs) );
+
+    if ( SP_COLOR_SELECTOR(cs)->base )
+    {
+        SP_COLOR_SELECTOR(cs)->base->init();
+    }
+}
+
+
+/*
+icSigRgbData
+icSigCmykData
+icSigCmyData
+*/
+#define SPACE_ID_RGB 0
+#define SPACE_ID_CMY 1
+#define SPACE_ID_CMYK 2
+
+
+static icUInt16Number* getScratch() {
+    // bytes per pixel * input channels * width
+    static icUInt16Number* scritch = static_cast<icUInt16Number*>(g_new(icUInt16Number, 4 * 1024));
+
+    return scritch;
+}
+
+struct MapMap {
+    DWORD space;
+    DWORD inForm;
+};
+
+void getThings( DWORD space, gchar const**& namers, gchar const**& tippies, bool const*& trickies, guint const*& scalies, DWORD& inputFormat ) {
+
+    MapMap possible[] = {
+        {icSigXYZData,   TYPE_XYZ_16},
+        {icSigLabData,   TYPE_Lab_16},
+        //icSigLuvData
+        {icSigYCbCrData, TYPE_YCbCr_16},
+        {icSigYxyData,   TYPE_Yxy_16},
+        {icSigRgbData,   TYPE_RGB_16},
+        {icSigGrayData,  TYPE_GRAY_16},
+        {icSigHsvData,   TYPE_HSV_16},
+        {icSigHlsData,   TYPE_HLS_16},
+        {icSigCmykData,  TYPE_CMYK_16},
+        {icSigCmyData,   TYPE_CMY_16},
+    };
+
+    static gchar const *names[][6] = {
+        {"_X", "_Y", "_Z", "", "", ""},
+        {"_L", "_a", "_b", "", "", ""},
+        //
+        {"_Y", "C_b", "C_r", "", "", ""},
+        {"_Y", "_x", "y", "", "", ""},
+        {_("_R"), _("_G"), _("_B"), "", "", ""},
+        {_("_G"), "", "", "", "", ""},
+        {_("_H"), _("_S"), "_V", "", "", ""},
+        {_("_H"), _("_L"), _("_S"), "", "", ""},
+        {_("_C"), _("_M"), _("_Y"), _("_K"), "", ""},
+        {_("_C"), _("_M"), _("_Y"), "", "", ""},
+    };
+
+    static gchar const *tips[][6] = {
+        {"X", "Y", "Z", "", "", ""},
+        {"L", "a", "b", "", "", ""},
+        //
+        {"Y", "Cb", "Cr", "", "", ""},
+        {"Y", "x", "y", "", "", ""},
+        {_("Red"), _("Green"), _("Blue"), "", "", ""},
+        {_("Gray"), "", "", "", "", ""},
+        {_("Hue"), _("Saturation"), "Value", "", "", ""},
+        {_("Hue"), _("Lightness"), _("Saturation"), "", "", ""},
+        {_("Cyan"), _("Magenta"), _("Yellow"), _("Black"), "", ""},
+        {_("Cyan"), _("Magenta"), _("Yellow"), "", "", ""},
+    };
+
+    static bool tricksies[][6] = {
+        {false, false, false, false, false, false}, // XYZ       0~2, 0~1, 0~2
+        {false, true,  true,  false, false, false}, // Lab       0~100, -128~128, -128~128
+        // Luv 0~100, -128~128, -128~128
+        {false, true,  true,  false, false, false}, // YCbCr     ?
+        {false, true,  true,  false, false, false}, // Yxy       0~1, 0~1, 0~1
+        {false, false, false, false, false, false}, // RGB       0~1, 0~1, 0~1
+        {false, false, false, false, false, false}, // Gray      0~1
+        {true,  false, false, false, false, false}, // HSV       0~360, 0~1, 0~1
+        {true,  false, false, false, false, false}, // HLS       0~360, 0~1, 0~1
+        {false, false, false, false, false, false}, // CMYK      0~1, 0~1, 0~1, 0~1
+        {false, false, false, false, false, false}, // CMY
+    };
+
+    static guint scales[][6] = {
+        {2, 1, 2, 1, 1, 1},
+        {100, 256, 256, 1, 1, 1},
+        //
+        {1, 1, 1, 1, 1, 1},
+        {1, 1, 1, 1, 1, 1},
+        {1, 1, 1, 1, 1, 1},
+        {1, 1, 1, 1, 1, 1},
+        {360, 1, 1, 1, 1, 1},
+        {360, 1, 1, 1, 1, 1},
+        {1, 1, 1, 1, 1, 1},
+        {1, 1, 1, 1, 1, 1},
+    };
+
+    int index = 0;
+    for ( guint i = 0; i < G_N_ELEMENTS(possible); i++ ) {
+        if ( possible[i].space == space ) {
+            index = i;
+            break;
+        }
+    }
+
+    inputFormat = possible[index].inForm;
+    namers = names[index];
+    tippies = tips[index];
+    trickies = tricksies[index];
+    scalies = scales[index];
+}
+
+
+void ColorICCSelector::init()
+{
+    GtkWidget *t;
+    gint row = 0;
+
+    _updating = FALSE;
+    _dragging = FALSE;
+
+    _tt = gtk_tooltips_new();
+
+    t = gtk_table_new (5, 3, FALSE);
+    gtk_widget_show (t);
+    gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 0);
+
+    DWORD inputFormat = TYPE_RGB_16;
+    //guint partCount = _cmsChannelsOf( icSigRgbData );
+    gchar const** names = 0;
+    gchar const** tips = 0;
+    bool const* tricky = 0;
+    getThings( icSigRgbData, names, tips, tricky, _fooScales, inputFormat );
+
+
+    /* Create components */
+    row = 0;
+
+
+    _fooCount = 4;
+    _fooAdj = new GtkAdjustment*[_fooCount];
+    _fooSlider = new GtkWidget*[_fooCount];
+    _fooBtn = new GtkWidget*[_fooCount];
+    _fooLabel = new GtkWidget*[_fooCount];
+    _fooMap = new guchar*[_fooCount];
+
+    for ( guint i = 0; i < _fooCount; i++ ) {
+        /* Label */
+        _fooLabel[i] = gtk_label_new_with_mnemonic( names[i] );
+        gtk_misc_set_alignment( GTK_MISC (_fooLabel[i]), 1.0, 0.5 );
+        gtk_widget_show( _fooLabel[i] );
+        gtk_table_attach( GTK_TABLE (t), _fooLabel[i], 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD );
+
+        /* Adjustment */
+        gdouble step = static_cast<gdouble>(_fooScales[i]) / 100.0;
+        gdouble page = static_cast<gdouble>(_fooScales[i]) / 10.0;
+        gint digits = (step > 0.9) ? 0 : 2;
+        _fooAdj[i] = GTK_ADJUSTMENT( gtk_adjustment_new( 0.0, 0.0, _fooScales[i],  step, page, page ) );
+
+        /* Slider */
+        _fooSlider[i] = sp_color_slider_new( _fooAdj[i] );
+        gtk_tooltips_set_tip( _tt, _fooSlider[i], tips[i], NULL );
+        gtk_widget_show( _fooSlider[i] );
+        gtk_table_attach( GTK_TABLE (t), _fooSlider[i], 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)GTK_FILL, XPAD, YPAD );
+
+        _fooBtn[i] = gtk_spin_button_new( _fooAdj[i], step, digits );
+        gtk_tooltips_set_tip( _tt, _fooBtn[i], tips[i], NULL );
+        sp_dialog_defocus_on_enter( _fooBtn[i] );
+        gtk_label_set_mnemonic_widget( GTK_LABEL(_fooLabel[i]), _fooBtn[i] );
+        gtk_widget_show( _fooBtn[i] );
+        gtk_table_attach( GTK_TABLE (t), _fooBtn[i], 2, 3, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD );
+
+        _fooMap[i] = g_new( guchar, 4 * 1024 );
+        memset( _fooMap[i], 0x0ff, 1024 * 4 );
+
+
+        /* Signals */
+        gtk_signal_connect( GTK_OBJECT( _fooAdj[i] ), "value_changed", GTK_SIGNAL_FUNC( _adjustmentChanged ), _csel );
+
+        gtk_signal_connect( GTK_OBJECT( _fooSlider[i] ), "grabbed", GTK_SIGNAL_FUNC( _sliderGrabbed ), _csel );
+        gtk_signal_connect( GTK_OBJECT( _fooSlider[i] ), "released", GTK_SIGNAL_FUNC( _sliderReleased ), _csel );
+        gtk_signal_connect( GTK_OBJECT( _fooSlider[i] ), "changed", GTK_SIGNAL_FUNC( _sliderChanged ), _csel );
+
+        row++;
+    }
+
+    /* Label */
+    _label = gtk_label_new_with_mnemonic (_("_A"));
+    gtk_misc_set_alignment (GTK_MISC (_label), 1.0, 0.5);
+    gtk_widget_show (_label);
+    gtk_table_attach (GTK_TABLE (t), _label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
+
+    /* Adjustment */
+    _adj = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 10.0, 10.0);
+
+    /* Slider */
+    _slider = sp_color_slider_new (_adj);
+    gtk_tooltips_set_tip (_tt, _slider, _("Alpha (opacity)"), NULL);
+    gtk_widget_show (_slider);
+    gtk_table_attach (GTK_TABLE (t), _slider, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)GTK_FILL, XPAD, YPAD);
+
+    sp_color_slider_set_colors( SP_COLOR_SLIDER( _slider ),
+                                SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 0.0 ),
+                                SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 0.5 ),
+                                SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 1.0 ) );
+
+
+    /* Spinbutton */
+    _sbtn = gtk_spin_button_new (GTK_ADJUSTMENT (_adj), 1.0, 0);
+    gtk_tooltips_set_tip (_tt, _sbtn, _("Alpha (opacity)"), NULL);
+    sp_dialog_defocus_on_enter (_sbtn);
+    gtk_label_set_mnemonic_widget (GTK_LABEL(_label), _sbtn);
+    gtk_widget_show (_sbtn);
+    gtk_table_attach (GTK_TABLE (t), _sbtn, 2, 3, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD);
+
+    /* Signals */
+    gtk_signal_connect (GTK_OBJECT (_adj), "value_changed",
+                        GTK_SIGNAL_FUNC (_adjustmentChanged), _csel);
+
+    gtk_signal_connect (GTK_OBJECT (_slider), "grabbed",
+                        GTK_SIGNAL_FUNC (_sliderGrabbed), _csel);
+    gtk_signal_connect (GTK_OBJECT (_slider), "released",
+                        GTK_SIGNAL_FUNC (_sliderReleased), _csel);
+    gtk_signal_connect (GTK_OBJECT (_slider), "changed",
+                        GTK_SIGNAL_FUNC (_sliderChanged), _csel);
+}
+
+static void
+sp_color_icc_selector_destroy (GtkObject *object)
+{
+    if (((GtkObjectClass *) (parent_class))->destroy)
+        (* ((GtkObjectClass *) (parent_class))->destroy) (object);
+}
+
+static void
+sp_color_icc_selector_show_all (GtkWidget *widget)
+{
+    gtk_widget_show (widget);
+}
+
+static void
+sp_color_icc_selector_hide_all (GtkWidget *widget)
+{
+    gtk_widget_hide (widget);
+}
+
+GtkWidget *
+sp_color_icc_selector_new (void)
+{
+    SPColorICCSelector *csel;
+
+    csel = (SPColorICCSelector*)gtk_type_new (SP_TYPE_COLOR_ICC_SELECTOR);
+
+    return GTK_WIDGET (csel);
+}
+
+/* Helpers for setting color value */
+
+void ColorICCSelector::_colorChanged( const SPColor& color, gfloat alpha )
+{
+    _updating = TRUE;
+//     sp_color_icc_set_color( SP_COLOR_ICC( _icc ), &color );
+
+#ifdef DEBUG_LCMS
+    g_message( "/^^^^^^^^^  %p::_colorChanged(%08x:%s)", this,
+               color.toRGBA32(alpha), ( (color.icc) ? color.icc->colorProfile.c_str(): "<null>" )
+               );
+#endif // DEBUG_LCMS
+
+#ifdef DEBUG_LCMS
+    g_message("FLIPPIES!!!!     %p   '%s'", color.icc, (color.icc?color.icc->colorProfile.c_str():"<null>"));
+#endif // DEBUG_LCMS
+
+    ColorScales::setScaled( _adj, alpha );
+
+#if ENABLE_LCMS
+    _setProfile( color.icc );
+
+#endif // ENABLE_LCMS
+    _updateSliders();
+
+
+    _updating = FALSE;
+#ifdef DEBUG_LCMS
+    g_message( "\\_________  %p::_colorChanged()", this );
+#endif // DEBUG_LCMS
+}
+
+#if ENABLE_LCMS
+void ColorICCSelector::_setProfile( SVGICCColor* profile )
+{
+#ifdef DEBUG_LCMS
+    g_message( "/^^^^^^^^^  %p::_setProfile(%s)", this,
+               ( (profile) ? profile->colorProfile.c_str() : "<null>")
+               );
+#endif // DEBUG_LCMS
+    if ( _prof && (!profile || (_profileName != profile->colorProfile) ) ) {
+        // Need to clear out the prior one
+        _profileName.clear();
+        _profIntent = Inkscape::RENDERING_INTENT_UNKNOWN;
+        _profileSpace = icSigRgbData;
+        _profileClass = icSigInputClass;
+        _prof = 0;
+        if ( _transf ) {
+            cmsDeleteTransform( _transf );
+            _transf = 0;
+        }
+        if ( _destProf ) {
+            cmsCloseProfile( _destProf );
+            _destProf = 0;
+        }
+        _profChannelCount = 0;
+    }
+
+    if ( profile ) {
+        _prof = Inkscape::colorprofile_get_handle( inkscape_active_document(),//SP_OBJECT_DOCUMENT( object ),
+                                                   &_profIntent,
+                                                   profile->colorProfile.c_str() );
+        if ( _prof ) {
+            _profileSpace = cmsGetColorSpace( _prof );
+            _profileClass = cmsGetDeviceClass( _prof );
+            if ( _profileClass != icSigNamedColorClass ) {
+                int intent = INTENT_PERCEPTUAL;
+                switch ( _profIntent ) {
+                    case Inkscape::RENDERING_INTENT_RELATIVE_COLORIMETRIC:
+                        intent = INTENT_RELATIVE_COLORIMETRIC;
+                        break;
+                    case Inkscape::RENDERING_INTENT_SATURATION:
+                        intent = INTENT_SATURATION;
+                        break;
+                    case Inkscape::RENDERING_INTENT_ABSOLUTE_COLORIMETRIC:
+                        intent = INTENT_ABSOLUTE_COLORIMETRIC;
+                        break;
+                    case Inkscape::RENDERING_INTENT_PERCEPTUAL:
+                    case Inkscape::RENDERING_INTENT_UNKNOWN:
+                    case Inkscape::RENDERING_INTENT_AUTO:
+                    default:
+                        intent = INTENT_PERCEPTUAL;
+                }
+                _destProf = cmsCreate_sRGBProfile();
+
+                _profChannelCount = _cmsChannelsOf( _profileSpace );
+
+                DWORD inputFormat = TYPE_RGB_16;
+                gchar const** names = 0;
+                gchar const** tips = 0;
+                bool const* tricky = 0;
+                getThings( _profileSpace, names, tips, tricky, _fooScales, inputFormat );
+
+                _transf = cmsCreateTransform( _prof, inputFormat, _destProf, TYPE_RGBA_8, intent, 0 );
+                (void)names;
+                (void)tips;
+                (void)tricky;
+
+
+            } else {
+                // Give up for now on named colors
+                _prof = 0;
+            }
+        }
+    }
+#ifdef DEBUG_LCMS
+    g_message( "\\_________  %p::_setProfile()", this );
+#endif // DEBUG_LCMS
+}
+#endif // ENABLE_LCMS
+
+void ColorICCSelector::_updateSliders()
+{
+#ifdef ENABLE_LCMS
+    if ( _color.icc )
+    {
+        DWORD inputFormat = TYPE_RGB_16;
+        gchar const** names = 0;
+        gchar const** tips = 0;
+        bool const* tricky = 0;
+        getThings( _profileSpace, names, tips, tricky, _fooScales, inputFormat );
+
+        for ( guint i = 0; i < _fooCount; i++ ) {
+            gtk_label_set_text_with_mnemonic( GTK_LABEL(_fooLabel[i]), names[i]);
+
+            gtk_tooltips_set_tip( _tt, _fooSlider[i], tips[i], NULL );
+            gtk_tooltips_set_tip( _tt, _fooBtn[i], tips[i], NULL );
+
+            sp_color_slider_set_colors( SP_COLOR_SLIDER(_fooSlider[i]),
+                                        SPColor(0.0, 0.0, 0.0).toRGBA32(0xff),
+                                        SPColor(0.5, 0.5, 0.5).toRGBA32(0xff),
+                                        SPColor(1.0, 1.0, 1.0).toRGBA32(0xff) );
+
+            if ( i < _profChannelCount ) {
+/*
+                gdouble step = static_cast<gdouble>(_fooScales[i]) / 100.0;
+                gdouble page = static_cast<gdouble>(_fooScales[i]) / 10.0;
+                gint digits = (step > 0.9) ? 0 : 2;
+*/
+                gdouble val = (_color.icc->colors.size() > i) ? (_color.icc->colors[i] / static_cast<gdouble>(_fooScales[i])) : 0.0;
+
+/*
+                _fooAdj[i] = GTK_ADJUSTMENT( gtk_adjustment_new( val, 0.0, _fooScales[i],  step, page, page ) );
+                gtk_signal_connect( GTK_OBJECT( _fooAdj[i] ), "value_changed", GTK_SIGNAL_FUNC( _adjustmentChanged ), _csel );
+
+                sp_color_slider_set_adjustment( SP_COLOR_SLIDER(_fooSlider[i]), _fooAdj[i] );
+                gtk_spin_button_set_adjustment( GTK_SPIN_BUTTON(_fooBtn[i]), _fooAdj[i] );
+                gtk_spin_button_set_digits( GTK_SPIN_BUTTON(_fooBtn[i]), digits );
+*/
+                gtk_widget_show( _fooLabel[i] );
+                gtk_widget_show( _fooSlider[i] );
+                gtk_widget_show( _fooBtn[i] );
+                gtk_adjustment_set_value( _fooAdj[i], val );
+            } else {
+                gtk_widget_hide( _fooLabel[i] );
+                gtk_widget_hide( _fooSlider[i] );
+                gtk_widget_hide( _fooBtn[i] );
+                gtk_adjustment_set_value( _fooAdj[i], 0.0 );
+            }
+
+        }
+
+        if ( _transf ) {
+            for ( guint i = 0; i < _profChannelCount; i++ ) {
+                if ( tricky[i] ) {
+                    icUInt16Number* scratch = getScratch();
+                    icUInt16Number filler[4] = {0, 0, 0, 0};
+                    for ( guint j = 0; j < _profChannelCount; j++ ) {
+                        filler[j] = 0x0ffff * ColorScales::getScaled( _fooAdj[i] );
+                    }
+
+                    icUInt16Number* p = scratch;
+                    for ( guint x = 0; x < 1024; x++ ) {
+                        if ( _profileSpace == icSigLabData && (i == 1 || i == 2) ) {
+                            p = scratch + 3 * ( (x + 512) % 1024);
+                        }
+                        for ( guint j = 0; j < _profChannelCount; j++ ) {
+                            if ( j == i ) {
+                                *p++ = x * 0x0ffff / 1024;
+                            } else {
+                                *p++ = filler[j];
+                            }
+                        }
+                    }
+
+                    cmsDoTransform( _transf, scratch, _fooMap[i], 1024 );
+                    sp_color_slider_set_map( SP_COLOR_SLIDER(_fooSlider[i]), _fooMap[i] );
+                } else {
+                    icUInt16Number tmp[4];
+                    for ( guint j = 0; j < _profChannelCount; j++ ) {
+                        tmp[j] = ColorScales::getScaled( _fooAdj[j] ) * 0x0ffff;
+                    }
+                    tmp[i] = 0;
+                    guchar post[4] = {0,0,0,0};
+                    cmsDoTransform( _transf, tmp, post, 1 );
+                    guint32 lowColor = SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255);
+
+                    tmp[i] = 0x0ffff/2;
+                    cmsDoTransform( _transf, tmp, post, 1 );
+                    guint32 midColor = SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255);
+
+                    tmp[i] = 0x0ffff;
+                    cmsDoTransform( _transf, tmp, post, 1 );
+                    guint32 highColor = SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255);
+
+                    sp_color_slider_set_colors( SP_COLOR_SLIDER(_fooSlider[i]), lowColor, midColor, highColor );
+                }
+            }
+        }
+    }
+#endif // ENABLE_LCMS
+
+    guint32 start = _color.toRGBA32( 0x00 );
+    guint32 mid = _color.toRGBA32( 0x7f );
+    guint32 end = _color.toRGBA32( 0xff );
+
+    sp_color_slider_set_colors( SP_COLOR_SLIDER(_slider), start, mid, end );
+
+}
+
+
+void ColorICCSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorICCSelector *cs )
+{
+// // TODO check this. It looks questionable:
+//     // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255  or 0..100
+//     if (adjustment->value > 0.0 && adjustment->value < 1.0) {
+//         gtk_adjustment_set_value( adjustment, floor ((adjustment->value) * adjustment->upper + 0.5) );
+//     }
+
+#ifdef DEBUG_LCMS
+    g_message( "/^^^^^^^^^  %p::_adjustmentChanged()", cs );
+#endif // DEBUG_LCMS
+
+     ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base);
+     if (iccSelector->_updating) {
+         return;
+     }
+
+     iccSelector->_updating = TRUE;
+
+     SPColor newColor( iccSelector->_color );
+     gfloat scaled = ColorScales::getScaled( iccSelector->_adj );
+     if ( iccSelector->_adj == adjustment ) {
+#ifdef DEBUG_LCMS
+         g_message("ALPHA");
+#endif // DEBUG_LCMS
+     } else {
+         gint match = -1;
+         for ( guint i = 0; i < iccSelector->_fooCount; i++ ) {
+             if ( iccSelector->_fooAdj[i] == adjustment ) {
+                 match = i;
+                 break;
+             }
+         }
+         if ( match >= 0 ) {
+#ifdef DEBUG_LCMS
+             g_message(" channel %d", match );
+#endif // DEBUG_LCMS
+         }
+
+
+         icUInt16Number tmp[4];
+         for ( guint i = 0; i < 4; i++ ) {
+             tmp[i] = ColorScales::getScaled( iccSelector->_fooAdj[i] ) * 0x0ffff;
+         }
+         guchar post[4] = {0,0,0,0};
+
+         cmsDoTransform( iccSelector->_transf, tmp, post, 1 );
+
+         SPColor other( SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255) );
+         other.icc = new SVGICCColor();
+         if ( iccSelector->_color.icc ) {
+             other.icc->colorProfile = iccSelector->_color.icc->colorProfile;
+         }
+
+         guint32 prior = iccSelector->_color.toRGBA32(255);
+         guint32 newer = other.toRGBA32(255);
+
+         if ( prior != newer ) {
+#ifdef DEBUG_LCMS
+             g_message("Transformed color from 0x%08x to 0x%08x", prior, newer );
+             g_message("      ~~~~ FLIP");
+#endif // DEBUG_LCMS
+             newColor = other;
+             newColor.icc->colors.clear();
+             for ( guint i = 0; i < iccSelector->_profChannelCount; i++ ) {
+                 gdouble val = ColorScales::getScaled( iccSelector->_fooAdj[i] );
+                 if ( iccSelector->_fooScales ) {
+                     val *= iccSelector->_fooScales[i];
+                 }
+                 newColor.icc->colors.push_back( val );
+             }
+         }
+
+     }
+     iccSelector->_updateInternals( newColor, scaled, iccSelector->_dragging );
+     iccSelector->_updateSliders();
+
+     iccSelector->_updating = FALSE;
+#ifdef DEBUG_LCMS
+     g_message( "\\_________  %p::_adjustmentChanged()", cs );
+#endif // DEBUG_LCMS
+}
+
+void ColorICCSelector::_sliderGrabbed( SPColorSlider *slider, SPColorICCSelector *cs )
+{
+    (void)slider;
+    (void)cs;
+//    ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base);
+//     if (!iccSelector->_dragging) {
+//         iccSelector->_dragging = TRUE;
+//         iccSelector->_grabbed();
+//         iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), iccSelector->_dragging );
+//     }
+}
+
+void ColorICCSelector::_sliderReleased( SPColorSlider *slider, SPColorICCSelector *cs )
+{
+    (void)slider;
+    (void)cs;
+//     ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base);
+//     if (iccSelector->_dragging) {
+//         iccSelector->_dragging = FALSE;
+//         iccSelector->_released();
+//         iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), iccSelector->_dragging );
+//     }
+}
+
+void ColorICCSelector::_sliderChanged( SPColorSlider *slider, SPColorICCSelector *cs )
+{
+    (void)slider;
+    (void)cs;
+#ifdef DEBUG_LCMS
+    g_message("Changed  %p and %p", slider, cs );
+#endif // DEBUG_LCMS
+//     ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base);
+
+//     iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), iccSelector->_dragging );
+}
+
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/sp-color-icc-selector.h b/src/widgets/sp-color-icc-selector.h
new file mode 100644 (file)
index 0000000..e29d167
--- /dev/null
@@ -0,0 +1,115 @@
+#ifndef __SP_COLOR_ICC_SELECTOR_H__
+#define __SP_COLOR_ICC_SELECTOR_H__
+
+#include <glib/gtypes.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtkvbox.h>
+
+#include "../color.h"
+#include "sp-color-slider.h"
+#include "sp-color-selector.h"
+
+#if ENABLE_LCMS
+#include "color-profile.h"
+#endif // ENABLE_LCMS
+
+
+
+struct SPColorICCSelector;
+struct SPColorICCSelectorClass;
+
+
+class ColorICCSelector: public ColorSelector
+{
+public:
+    ColorICCSelector( SPColorSelector* csel );
+    virtual ~ColorICCSelector();
+
+    virtual void init();
+
+protected:
+    virtual void _colorChanged( const SPColor& color, gfloat alpha );
+
+    static void _adjustmentChanged ( GtkAdjustment *adjustment, SPColorICCSelector *cs );
+
+    static void _sliderGrabbed( SPColorSlider *slider, SPColorICCSelector *cs );
+    static void _sliderReleased( SPColorSlider *slider, SPColorICCSelector *cs );
+    static void _sliderChanged( SPColorSlider *slider, SPColorICCSelector *cs );
+
+    static void _fooChanged( GtkWidget foo, SPColorICCSelector *cs );
+
+    void _recalcColor( gboolean changing );
+#if ENABLE_LCMS
+    void _setProfile( SVGICCColor* profile );
+#endif // ENABLE_LCMS
+    void _updateSliders();
+
+    gboolean _updating : 1;
+    gboolean _dragging : 1;
+
+    guint _fooCount;
+    guint const* _fooScales;
+    GtkAdjustment** _fooAdj;
+    GtkWidget** _fooSlider;
+    GtkWidget** _fooBtn;
+    GtkWidget** _fooLabel;
+    guchar** _fooMap;
+
+    GtkAdjustment* _adj; /* Channel adjustment */
+    GtkWidget* _slider;
+    GtkWidget* _sbtn; /* Spinbutton */
+    GtkWidget* _label; /* Label */
+
+    GtkTooltips* _tt; /* tooltip container */
+
+#if ENABLE_LCMS
+    std::string _profileName;
+    guint _profIntent;
+    icColorSpaceSignature _profileSpace;
+    icProfileClassSignature _profileClass;
+    cmsHPROFILE _prof;
+    cmsHPROFILE _destProf;
+    cmsHTRANSFORM _transf;
+    guint _profChannelCount;
+#endif // ENABLE_LCMS
+
+private:
+    // By default, disallow copy constructor and assignment operator
+    ColorICCSelector( const ColorICCSelector& obj );
+    ColorICCSelector& operator=( const ColorICCSelector& obj );
+};
+
+
+
+#define SP_TYPE_COLOR_ICC_SELECTOR (sp_color_icc_selector_get_type ())
+#define SP_COLOR_ICC_SELECTOR(o) (GTK_CHECK_CAST ((o), SP_TYPE_COLOR_ICC_SELECTOR, SPColorICCSelector))
+#define SP_COLOR_ICC_SELECTOR_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), SP_TYPE_COLOR_ICC_SELECTOR, SPColorICCSelectorClass))
+#define SP_IS_COLOR_ICC_SELECTOR(o) (GTK_CHECK_TYPE ((o), SP_TYPE_COLOR_ICC_SELECTOR))
+#define SP_IS_COLOR_ICC_SELECTOR_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), SP_TYPE_COLOR_ICC_SELECTOR))
+
+struct SPColorICCSelector {
+    SPColorSelector parent;
+};
+
+struct SPColorICCSelectorClass {
+    SPColorSelectorClass parent_class;
+};
+
+GType sp_color_icc_selector_get_type (void);
+
+GtkWidget *sp_color_icc_selector_new (void);
+
+
+
+#endif
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index 60617b849f7560eb720b8426a7bce0c9980338be..44d6b3799e6aafc184d6d3ef589aa3c2c4914c81 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #undef SPCS_PREVIEW
+#define noDUMP_CHANGE_INFO
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -28,6 +29,7 @@
 
 #include "sp-color-scales.h"
 #include "sp-color-wheel-selector.h"
+#include "sp-color-icc-selector.h"
 
 struct SPColorNotebookTracker {
        const gchar* name;
@@ -40,7 +42,7 @@ struct SPColorNotebookTracker {
 };
 
 static void sp_color_notebook_class_init (SPColorNotebookClass *klass);
-static void sp_color_notebook_init (SPColorNotebook *slider);
+static void sp_color_notebook_init (SPColorNotebook *colorbook);
 static void sp_color_notebook_destroy (GtkObject *object);
 
 static void sp_color_notebook_show_all (GtkWidget *widget);
@@ -196,6 +198,9 @@ void ColorNotebook::init()
        /* tempory hardcoding to get types loaded */
        SP_TYPE_COLOR_SCALES;
        SP_TYPE_COLOR_WHEEL_SELECTOR;
+#if ENABLE_LCMS
+       SP_TYPE_COLOR_ICC_SELECTOR;
+#endif // ENABLE_LCMS
 
        /* REJON: Comment out the next line to not use the normal GTK Color
            wheel. */
index ec80eff3e099087e751e88fca3145c1735b85284..05299624791ebedbe29bab9618217b0455e1d685 100644 (file)
@@ -204,6 +204,8 @@ gfloat ColorSelector::getAlpha() const
     return _alpha;
 }
 
+#include "svg/svg-icc-color.h"
+
 /**
 Called from the outside to set the color; optionally emits signal (only when called from
 downstream, e.g. the RGBA value field, but not from the rest of the program)
@@ -211,15 +213,16 @@ downstream, e.g. the RGBA value field, but not from the rest of the program)
 void ColorSelector::setColorAlpha( const SPColor& color, gfloat alpha, bool emit )
 {
 #ifdef DUMP_CHANGE_INFO
-    g_message("ColorSelector::setColorAlpha( this=%p, %f, %f, %f,   %f,   %s)", this, color.v.c[0], color.v.c[1], color.v.c[2], alpha, (emit?"YES":"no"));
+    g_message("ColorSelector::setColorAlpha( this=%p, %f, %f, %f, %s,   %f,   %s) in %s", this, color.v.c[0], color.v.c[1], color.v.c[2], (color.icc?color.icc->colorProfile.c_str():"<null>"), alpha, (emit?"YES":"no"), FOO_NAME(_csel));
 #endif
     g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
 
 #ifdef DUMP_CHANGE_INFO
-    g_message("---- ColorSelector::setColorAlpha    virgin:%s   !close:%s    alpha is:%s",
+    g_message("---- ColorSelector::setColorAlpha    virgin:%s   !close:%s    alpha is:%s in %s",
               (virgin?"YES":"no"),
               (!color.isClose( _color, _epsilon )?"YES":"no"),
-                  ((fabs ((_alpha) - (alpha)) >= _epsilon )?"YES":"no")
+              ((fabs ((_alpha) - (alpha)) >= _epsilon )?"YES":"no"),
+              FOO_NAME(_csel)
               );
 #endif
 
@@ -236,8 +239,8 @@ void ColorSelector::setColorAlpha( const SPColor& color, gfloat alpha, bool emit
                gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[CHANGED]);
 #ifdef DUMP_CHANGE_INFO
     } else {
-        g_message("++++ ColorSelector::setColorAlpha   color:%08x  ==>  _color:%08X   isClose", color.toRGBA32(alpha), _color.toRGBA32(_alpha),
-                  (color.isClose( _color, _epsilon )?"YES":"no"));
+        g_message("++++ ColorSelector::setColorAlpha   color:%08x  ==>  _color:%08X   isClose:%s   in %s", color.toRGBA32(alpha), _color.toRGBA32(_alpha),
+                  (color.isClose( _color, _epsilon )?"YES":"no"), FOO_NAME(_csel));
 #endif
     }
 }
@@ -286,18 +289,18 @@ void ColorSelector::_updateInternals( const SPColor& color, gfloat alpha, gboole
     if ( grabbed )
     {
 #ifdef DUMP_CHANGE_INFO
-        g_message ("%s:%d: About to signal %s to color %08x in %s", __FILE__, __LINE__,
+        g_message ("%s:%d: About to signal %s to color %08x::%s in %s", __FILE__, __LINE__,
                    "GRABBED",
-                   color.toRGBA32( alpha ), FOO_NAME(_csel));
+                   color.toRGBA32( alpha ), (color.icc?color.icc->colorProfile.c_str():"<null>"), FOO_NAME(_csel));
 #endif
         gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[GRABBED]);
     }
     else if ( released )
     {
 #ifdef DUMP_CHANGE_INFO
-        g_message ("%s:%d: About to signal %s to color %08x in %s", __FILE__, __LINE__,
+        g_message ("%s:%d: About to signal %s to color %08x::%s in %s", __FILE__, __LINE__,
                    "RELEASED",
-                   color.toRGBA32( alpha ), FOO_NAME(_csel));
+                   color.toRGBA32( alpha ), (color.icc?color.icc->colorProfile.c_str():"<null>"), FOO_NAME(_csel));
 #endif
         gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[RELEASED]);
     }
@@ -305,9 +308,9 @@ void ColorSelector::_updateInternals( const SPColor& color, gfloat alpha, gboole
     if ( colorDifferent || released )
     {
 #ifdef DUMP_CHANGE_INFO
-        g_message ("%s:%d: About to signal %s to color %08x in %s", __FILE__, __LINE__,
+        g_message ("%s:%d: About to signal %s to color %08x::%s in %s", __FILE__, __LINE__,
                    (_held ? "CHANGED" : "DRAGGED" ),
-                   color.toRGBA32( alpha ), FOO_NAME(_csel));
+                   color.toRGBA32( alpha ), (color.icc?color.icc->colorProfile.c_str():"<null>"), FOO_NAME(_csel));
 #endif
         gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[_held ? CHANGED : DRAGGED]);
     }
index 76ef13a8dac8396b44e837902497431a7a934217..b3c775c372c96fe53019ae2150b6cf72483d02d7 100644 (file)
@@ -360,6 +360,9 @@ sp_color_slider_set_colors (SPColorSlider *slider, guint32 start, guint32 mid, g
        g_return_if_fail (slider != NULL);
        g_return_if_fail (SP_IS_COLOR_SLIDER (slider));
 
+        // Remove any map, if set
+        slider->map = 0;
+
        slider->c0[0] = start >> 24;
        slider->c0[1] = (start >> 16) & 0xff;
        slider->c0[2] = (start >> 8) & 0xff;