Code

Adding profile manager and user-visible drop-down in CMS picker
[inkscape.git] / src / widgets / sp-color-icc-selector.cpp
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4 #include <math.h>
5 #include <gtk/gtkbutton.h>
6 #include <gtk/gtkcombobox.h>
7 #include <gtk/gtksignal.h>
8 #include <gtk/gtklabel.h>
9 #include <gtk/gtktable.h>
10 #include <gtk/gtkspinbutton.h>
11 #include <glibmm/i18n.h>
12 #include "../dialogs/dialog-events.h"
13 #include "sp-color-icc-selector.h"
14 #include "sp-color-scales.h"
15 #include "svg/svg-icc-color.h"
16 #include "document.h"
17 #include "inkscape.h"
19 #define noDEBUG_LCMS
21 #if ENABLE_LCMS
22 #include "color-profile-fns.h"
23 #include "color-profile.h"
24 //#define DEBUG_LCMS
25 #ifdef DEBUG_LCMS
26 #include "prefs-utils.h"
27 #include <gtk/gtkmessagedialog.h>
28 #endif // DEBUG_LCMS
29 #endif // ENABLE_LCMS
32 #ifdef DEBUG_LCMS
33 extern guint update_in_progress;
34 #define DEBUG_MESSAGE(key, ...) \
35 {\
36     gint dump = prefs_get_int_attribute_limited("options.scislac", #key, 0, 0, 1);\
37     gint dumpD = prefs_get_int_attribute_limited("options.scislac", #key"D", 0, 0, 1);\
38     gint dumpD2 = prefs_get_int_attribute_limited("options.scislac", #key"D2", 0, 0, 1);\
39     dumpD &= ( (update_in_progress == 0) || dumpD2 );\
40     if ( dump )\
41     {\
42         g_message( __VA_ARGS__ );\
43 \
44     }\
45     if ( dumpD )\
46     {\
47         GtkWidget *dialog = gtk_message_dialog_new(NULL,\
48                                                    GTK_DIALOG_DESTROY_WITH_PARENT, \
49                                                    GTK_MESSAGE_INFO,    \
50                                                    GTK_BUTTONS_OK,      \
51                                                    __VA_ARGS__          \
52                                                    );\
53         g_signal_connect_swapped(dialog, "response",\
54                                  G_CALLBACK(gtk_widget_destroy),        \
55                                  dialog);                               \
56         gtk_widget_show_all( dialog );\
57     }\
58 }
59 #endif // DEBUG_LCMS
63 G_BEGIN_DECLS
65 static void sp_color_icc_selector_class_init (SPColorICCSelectorClass *klass);
66 static void sp_color_icc_selector_init (SPColorICCSelector *cs);
67 static void sp_color_icc_selector_destroy (GtkObject *object);
69 static void sp_color_icc_selector_show_all (GtkWidget *widget);
70 static void sp_color_icc_selector_hide_all (GtkWidget *widget);
73 G_END_DECLS
75 static SPColorSelectorClass *parent_class;
77 #define XPAD 4
78 #define YPAD 1
80 GType
81 sp_color_icc_selector_get_type (void)
82 {
83     static GType type = 0;
84     if (!type) {
85         static const GTypeInfo info = {
86             sizeof (SPColorICCSelectorClass),
87             NULL, /* base_init */
88             NULL, /* base_finalize */
89             (GClassInitFunc) sp_color_icc_selector_class_init,
90             NULL, /* class_finalize */
91             NULL, /* class_data */
92             sizeof (SPColorICCSelector),
93             0,    /* n_preallocs */
94             (GInstanceInitFunc) sp_color_icc_selector_init,
95             0,    /* value_table */
96         };
98         type = g_type_register_static (SP_TYPE_COLOR_SELECTOR,
99                                        "SPColorICCSelector",
100                                        &info,
101                                        static_cast< GTypeFlags > (0) );
102     }
103     return type;
106 static void
107 sp_color_icc_selector_class_init (SPColorICCSelectorClass *klass)
109     static const gchar* nameset[] = {N_("CMS"), 0};
110     GtkObjectClass *object_class;
111     GtkWidgetClass *widget_class;
112     SPColorSelectorClass *selector_class;
114     object_class = (GtkObjectClass *) klass;
115     widget_class = (GtkWidgetClass *) klass;
116     selector_class = SP_COLOR_SELECTOR_CLASS (klass);
118     parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass));
120     selector_class->name = nameset;
121     selector_class->submode_count = 1;
123     object_class->destroy = sp_color_icc_selector_destroy;
125     widget_class->show_all = sp_color_icc_selector_show_all;
126     widget_class->hide_all = sp_color_icc_selector_hide_all;
129 ColorICCSelector::ColorICCSelector( SPColorSelector* csel )
130     : ColorSelector( csel ),
131       _updating( FALSE ),
132       _dragging( FALSE ),
133       _fixupNeeded(0),
134       _fooCount(0),
135       _fooScales(0),
136       _fooAdj(0),
137       _fooSlider(0),
138       _fooBtn(0),
139       _fooLabel(0),
140       _fooMap(0),
141       _adj(0),
142       _sbtn(0),
143       _label(0),
144       _tt(0)
145 #if ENABLE_LCMS
146     ,
147       _profileName(""),
148       _profIntent(Inkscape::RENDERING_INTENT_UNKNOWN),
149       _profileSpace(icSigRgbData),
150       _profileClass(icSigInputClass),
151       _prof(0),
152       _destProf(0),
153       _transf(0),
154       _profChannelCount(0)
155 #endif // ENABLE_LCMS
159 ColorICCSelector::~ColorICCSelector()
161     _adj = 0;
162     _sbtn = 0;
163     _label = 0;
166 void sp_color_icc_selector_init (SPColorICCSelector *cs)
168     SP_COLOR_SELECTOR(cs)->base = new ColorICCSelector( SP_COLOR_SELECTOR(cs) );
170     if ( SP_COLOR_SELECTOR(cs)->base )
171     {
172         SP_COLOR_SELECTOR(cs)->base->init();
173     }
177 /*
178 icSigRgbData
179 icSigCmykData
180 icSigCmyData
181 */
182 #define SPACE_ID_RGB 0
183 #define SPACE_ID_CMY 1
184 #define SPACE_ID_CMYK 2
187 #if ENABLE_LCMS
188 static icUInt16Number* getScratch() {
189     // bytes per pixel * input channels * width
190     static icUInt16Number* scritch = static_cast<icUInt16Number*>(g_new(icUInt16Number, 4 * 1024));
192     return scritch;
195 struct MapMap {
196     DWORD space;
197     DWORD inForm;
198 };
200 void getThings( DWORD space, gchar const**& namers, gchar const**& tippies, guint const*& scalies, DWORD& inputFormat ) {
201     MapMap possible[] = {
202         {icSigXYZData,   TYPE_XYZ_16},
203         {icSigLabData,   TYPE_Lab_16},
204         //icSigLuvData
205         {icSigYCbCrData, TYPE_YCbCr_16},
206         {icSigYxyData,   TYPE_Yxy_16},
207         {icSigRgbData,   TYPE_RGB_16},
208         {icSigGrayData,  TYPE_GRAY_16},
209         {icSigHsvData,   TYPE_HSV_16},
210         {icSigHlsData,   TYPE_HLS_16},
211         {icSigCmykData,  TYPE_CMYK_16},
212         {icSigCmyData,   TYPE_CMY_16},
213     };
215     static gchar const *names[][6] = {
216         {"_X", "_Y", "_Z", "", "", ""},
217         {"_L", "_a", "_b", "", "", ""},
218         //
219         {"_Y", "C_b", "C_r", "", "", ""},
220         {"_Y", "_x", "y", "", "", ""},
221         {_("_R"), _("_G"), _("_B"), "", "", ""},
222         {_("_G"), "", "", "", "", ""},
223         {_("_H"), _("_S"), "_V", "", "", ""},
224         {_("_H"), _("_L"), _("_S"), "", "", ""},
225         {_("_C"), _("_M"), _("_Y"), _("_K"), "", ""},
226         {_("_C"), _("_M"), _("_Y"), "", "", ""},
227     };
229     static gchar const *tips[][6] = {
230         {"X", "Y", "Z", "", "", ""},
231         {"L", "a", "b", "", "", ""},
232         //
233         {"Y", "Cb", "Cr", "", "", ""},
234         {"Y", "x", "y", "", "", ""},
235         {_("Red"), _("Green"), _("Blue"), "", "", ""},
236         {_("Gray"), "", "", "", "", ""},
237         {_("Hue"), _("Saturation"), "Value", "", "", ""},
238         {_("Hue"), _("Lightness"), _("Saturation"), "", "", ""},
239         {_("Cyan"), _("Magenta"), _("Yellow"), _("Black"), "", ""},
240         {_("Cyan"), _("Magenta"), _("Yellow"), "", "", ""},
241     };
243     static guint scales[][6] = {
244         {2, 1, 2, 1, 1, 1},
245         {100, 256, 256, 1, 1, 1},
246         //
247         {1, 1, 1, 1, 1, 1},
248         {1, 1, 1, 1, 1, 1},
249         {1, 1, 1, 1, 1, 1},
250         {1, 1, 1, 1, 1, 1},
251         {360, 1, 1, 1, 1, 1},
252         {360, 1, 1, 1, 1, 1},
253         {1, 1, 1, 1, 1, 1},
254         {1, 1, 1, 1, 1, 1},
255     };
257     int index = 0;
258     for ( guint i = 0; i < G_N_ELEMENTS(possible); i++ ) {
259         if ( possible[i].space == space ) {
260             index = i;
261             break;
262         }
263     }
265     inputFormat = possible[index].inForm;
266     namers = names[index];
267     tippies = tips[index];
268     scalies = scales[index];
270 #endif // ENABLE_LCMS
273 void ColorICCSelector::init()
275     GtkWidget *t;
276     gint row = 0;
278     _updating = FALSE;
279     _dragging = FALSE;
281     _tt = gtk_tooltips_new();
283     t = gtk_table_new (5, 3, FALSE);
284     gtk_widget_show (t);
285     gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 0);
287 #if ENABLE_LCMS
288     DWORD inputFormat = TYPE_RGB_16;
289     //guint partCount = _cmsChannelsOf( icSigRgbData );
290     gchar const** names = 0;
291     gchar const** tips = 0;
292     getThings( icSigRgbData, names, tips, _fooScales, inputFormat );
293 #endif // ENABLE_LCMS
295     /* Create components */
296     row = 0;
299     _fixupBtn = gtk_button_new_with_label(_("Fix"));
300     g_signal_connect( G_OBJECT(_fixupBtn), "clicked", G_CALLBACK(_fixupHit), (gpointer)this );
301     gtk_widget_set_sensitive( _fixupBtn, FALSE );
302     gtk_tooltips_set_tip( _tt, _fixupBtn, _("Fix RGB fallback to match icc-color() value."), NULL );
303     //gtk_misc_set_alignment( GTK_MISC (_fixupBtn), 1.0, 0.5 );
304     gtk_widget_show( _fixupBtn );
305     gtk_table_attach( GTK_TABLE (t), _fixupBtn, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD );
308     _profileSel = gtk_combo_box_new_text();
309     gtk_combo_box_append_text( GTK_COMBO_BOX(_profileSel), "<none>" );
310     gtk_widget_show( _profileSel );
311     gtk_combo_box_set_active( GTK_COMBO_BOX(_profileSel), 0 );
312     gtk_table_attach( GTK_TABLE(t), _profileSel, 1, 2, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD );
314     gtk_widget_set_sensitive( _profileSel, false );
316     row++;
318     _fooCount = 4;
319     _fooAdj = new GtkAdjustment*[_fooCount];
320     _fooSlider = new GtkWidget*[_fooCount];
321     _fooBtn = new GtkWidget*[_fooCount];
322     _fooLabel = new GtkWidget*[_fooCount];
323     _fooMap = new guchar*[_fooCount];
325     for ( guint i = 0; i < _fooCount; i++ ) {
326         /* Label */
327 #if ENABLE_LCMS
328         _fooLabel[i] = gtk_label_new_with_mnemonic( names[i] );
329 #else
330         _fooLabel[i] = gtk_label_new_with_mnemonic( "." );
331 #endif // ENABLE_LCMS
332         gtk_misc_set_alignment( GTK_MISC (_fooLabel[i]), 1.0, 0.5 );
333         gtk_widget_show( _fooLabel[i] );
334         gtk_table_attach( GTK_TABLE (t), _fooLabel[i], 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD );
336         /* Adjustment */
337         gdouble step = static_cast<gdouble>(_fooScales[i]) / 100.0;
338         gdouble page = static_cast<gdouble>(_fooScales[i]) / 10.0;
339         gint digits = (step > 0.9) ? 0 : 2;
340         _fooAdj[i] = GTK_ADJUSTMENT( gtk_adjustment_new( 0.0, 0.0, _fooScales[i],  step, page, page ) );
342         /* Slider */
343         _fooSlider[i] = sp_color_slider_new( _fooAdj[i] );
344 #if ENABLE_LCMS
345         gtk_tooltips_set_tip( _tt, _fooSlider[i], tips[i], NULL );
346 #else
347         gtk_tooltips_set_tip( _tt, _fooSlider[i], ".", NULL );
348 #endif // ENABLE_LCMS
349         gtk_widget_show( _fooSlider[i] );
350         gtk_table_attach( GTK_TABLE (t), _fooSlider[i], 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)GTK_FILL, XPAD, YPAD );
352         _fooBtn[i] = gtk_spin_button_new( _fooAdj[i], step, digits );
353 #if ENABLE_LCMS
354         gtk_tooltips_set_tip( _tt, _fooBtn[i], tips[i], NULL );
355 #else
356         gtk_tooltips_set_tip( _tt, _fooBtn[i], ".", NULL );
357 #endif // ENABLE_LCMS
358         sp_dialog_defocus_on_enter( _fooBtn[i] );
359         gtk_label_set_mnemonic_widget( GTK_LABEL(_fooLabel[i]), _fooBtn[i] );
360         gtk_widget_show( _fooBtn[i] );
361         gtk_table_attach( GTK_TABLE (t), _fooBtn[i], 2, 3, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD );
363         _fooMap[i] = g_new( guchar, 4 * 1024 );
364         memset( _fooMap[i], 0x0ff, 1024 * 4 );
367         /* Signals */
368         gtk_signal_connect( GTK_OBJECT( _fooAdj[i] ), "value_changed", GTK_SIGNAL_FUNC( _adjustmentChanged ), _csel );
370         gtk_signal_connect( GTK_OBJECT( _fooSlider[i] ), "grabbed", GTK_SIGNAL_FUNC( _sliderGrabbed ), _csel );
371         gtk_signal_connect( GTK_OBJECT( _fooSlider[i] ), "released", GTK_SIGNAL_FUNC( _sliderReleased ), _csel );
372         gtk_signal_connect( GTK_OBJECT( _fooSlider[i] ), "changed", GTK_SIGNAL_FUNC( _sliderChanged ), _csel );
374         row++;
375     }
377     /* Label */
378     _label = gtk_label_new_with_mnemonic (_("_A"));
379     gtk_misc_set_alignment (GTK_MISC (_label), 1.0, 0.5);
380     gtk_widget_show (_label);
381     gtk_table_attach (GTK_TABLE (t), _label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
383     /* Adjustment */
384     _adj = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 10.0, 10.0);
386     /* Slider */
387     _slider = sp_color_slider_new (_adj);
388     gtk_tooltips_set_tip (_tt, _slider, _("Alpha (opacity)"), NULL);
389     gtk_widget_show (_slider);
390     gtk_table_attach (GTK_TABLE (t), _slider, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)GTK_FILL, XPAD, YPAD);
392     sp_color_slider_set_colors( SP_COLOR_SLIDER( _slider ),
393                                 SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 0.0 ),
394                                 SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 0.5 ),
395                                 SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 1.0 ) );
398     /* Spinbutton */
399     _sbtn = gtk_spin_button_new (GTK_ADJUSTMENT (_adj), 1.0, 0);
400     gtk_tooltips_set_tip (_tt, _sbtn, _("Alpha (opacity)"), NULL);
401     sp_dialog_defocus_on_enter (_sbtn);
402     gtk_label_set_mnemonic_widget (GTK_LABEL(_label), _sbtn);
403     gtk_widget_show (_sbtn);
404     gtk_table_attach (GTK_TABLE (t), _sbtn, 2, 3, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD);
406     /* Signals */
407     gtk_signal_connect (GTK_OBJECT (_adj), "value_changed",
408                         GTK_SIGNAL_FUNC (_adjustmentChanged), _csel);
410     gtk_signal_connect (GTK_OBJECT (_slider), "grabbed",
411                         GTK_SIGNAL_FUNC (_sliderGrabbed), _csel);
412     gtk_signal_connect (GTK_OBJECT (_slider), "released",
413                         GTK_SIGNAL_FUNC (_sliderReleased), _csel);
414     gtk_signal_connect (GTK_OBJECT (_slider), "changed",
415                         GTK_SIGNAL_FUNC (_sliderChanged), _csel);
418 static void
419 sp_color_icc_selector_destroy (GtkObject *object)
421     if (((GtkObjectClass *) (parent_class))->destroy)
422         (* ((GtkObjectClass *) (parent_class))->destroy) (object);
425 static void
426 sp_color_icc_selector_show_all (GtkWidget *widget)
428     gtk_widget_show (widget);
431 static void
432 sp_color_icc_selector_hide_all (GtkWidget *widget)
434     gtk_widget_hide (widget);
437 GtkWidget *
438 sp_color_icc_selector_new (void)
440     SPColorICCSelector *csel;
442     csel = (SPColorICCSelector*)gtk_type_new (SP_TYPE_COLOR_ICC_SELECTOR);
444     return GTK_WIDGET (csel);
448 void ColorICCSelector::_fixupHit( GtkWidget* src, gpointer data )
450     (void)src;
451     ColorICCSelector* self = reinterpret_cast<ColorICCSelector*>(data);
452     gtk_widget_set_sensitive( self->_fixupBtn, FALSE );
453     self->_adjustmentChanged( self->_fooAdj[0], SP_COLOR_ICC_SELECTOR(self->_csel) );
456 void ColorICCSelector::_profilesChanged( std::string const & name )
458     GtkComboBox* combo = GTK_COMBO_BOX(_profileSel);
459     GtkTreeModel* model = gtk_combo_box_get_model( combo );
460     GtkTreeIter iter;
461     while ( gtk_tree_model_get_iter_first( model, &iter ) ) {
462         gtk_combo_box_remove_text( combo, 0 );
463     }
465     gtk_combo_box_append_text( combo, "<none>");
467     // TODO supress signal emit
468     gtk_combo_box_set_active( combo, 0 );
470     int index = 1;
471     const GSList *current = sp_document_get_resource_list( SP_ACTIVE_DOCUMENT, "iccprofile" );
472     while ( current ) {
473         SPObject* obj = SP_OBJECT(current->data);
474         Inkscape::ColorProfile* prof = reinterpret_cast<Inkscape::ColorProfile*>(obj);
475         gtk_combo_box_append_text( combo, prof->name );
476         if ( name == prof->name ) {
477             gtk_combo_box_set_active( combo, index );
478         }
480         index++;
481         current = g_slist_next(current);
482     }
486 /* Helpers for setting color value */
488 void ColorICCSelector::_colorChanged( const SPColor& color, gfloat alpha )
490     _updating = TRUE;
491 //     sp_color_icc_set_color( SP_COLOR_ICC( _icc ), &color );
493 #ifdef DEBUG_LCMS
494     g_message( "/^^^^^^^^^  %p::_colorChanged(%08x:%s)", this,
495                color.toRGBA32(alpha), ( (color.icc) ? color.icc->colorProfile.c_str(): "<null>" )
496                );
497 #endif // DEBUG_LCMS
499 #ifdef DEBUG_LCMS
500     g_message("FLIPPIES!!!!     %p   '%s'", color.icc, (color.icc?color.icc->colorProfile.c_str():"<null>"));
501 #endif // DEBUG_LCMS
503     _profilesChanged( (color.icc) ? color.icc->colorProfile : std::string("") );
504     ColorScales::setScaled( _adj, alpha );
506 #if ENABLE_LCMS
507     _setProfile( color.icc );
508     _fixupNeeded = 0;
509     gtk_widget_set_sensitive( _fixupBtn, FALSE );
511     if ( _transf ) {
512         icUInt16Number tmp[4];
513         for ( guint i = 0; i < _profChannelCount; i++ ) {
514             gdouble val = 0.0;
515             if ( _color.icc->colors.size() > i ) {
516                 if ( _fooScales[i] == 256 ) {
517                     val = (_color.icc->colors[i] + 128.0) / static_cast<gdouble>(_fooScales[i]);
518                 } else {
519                     val = _color.icc->colors[i] / static_cast<gdouble>(_fooScales[i]);
520                 }
521             }
522             tmp[i] = val * 0x0ffff;
523         }
524         guchar post[4] = {0,0,0,0};
525         cmsDoTransform( _transf, tmp, post, 1 );
526         guint32 other = SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255 );
527         if ( other != color.toRGBA32(255) ) {
528             _fixupNeeded = other;
529             gtk_widget_set_sensitive( _fixupBtn, TRUE );
530             //g_message("Color needs to change 0x%06x to 0x%06x", color.toRGBA32(255) >> 8, other >> 8 );
531         }
532     }
533 #else
534     (void)color;
535 #endif // ENABLE_LCMS
536     _updateSliders( -1 );
539     _updating = FALSE;
540 #ifdef DEBUG_LCMS
541     g_message( "\\_________  %p::_colorChanged()", this );
542 #endif // DEBUG_LCMS
545 #if ENABLE_LCMS
546 void ColorICCSelector::_setProfile( SVGICCColor* profile )
548 #ifdef DEBUG_LCMS
549     g_message( "/^^^^^^^^^  %p::_setProfile(%s)", this,
550                ( (profile) ? profile->colorProfile.c_str() : "<null>")
551                );
552 #endif // DEBUG_LCMS
553     bool profChanged = false;
554     if ( _prof && (!profile || (_profileName != profile->colorProfile) ) ) {
555         // Need to clear out the prior one
556         profChanged = true;
557         _profileName.clear();
558         _profIntent = Inkscape::RENDERING_INTENT_UNKNOWN;
559         _profileSpace = icSigRgbData;
560         _profileClass = icSigInputClass;
561         _prof = 0;
562         if ( _transf ) {
563             cmsDeleteTransform( _transf );
564             _transf = 0;
565         }
566         if ( _destProf ) {
567             cmsCloseProfile( _destProf );
568             _destProf = 0;
569         }
570         _profChannelCount = 0;
571     } else if ( profile && !_prof ) {
572         profChanged = true;
573     }
575     for ( guint i = 0; i < _fooCount; i++ ) {
576         gtk_widget_hide( _fooLabel[i] );
577         gtk_widget_hide( _fooSlider[i] );
578         gtk_widget_hide( _fooBtn[i] );
579         gtk_adjustment_set_value( _fooAdj[i], 0.0 );
580     }
582     if ( profile ) {
583         _prof = Inkscape::colorprofile_get_handle( inkscape_active_document(),//SP_OBJECT_DOCUMENT( object ),
584                                                    &_profIntent,
585                                                    profile->colorProfile.c_str() );
586         if ( _prof ) {
587             _profileSpace = cmsGetColorSpace( _prof );
588             _profileClass = cmsGetDeviceClass( _prof );
589             if ( _profileClass != icSigNamedColorClass ) {
590                 int intent = INTENT_PERCEPTUAL;
591                 switch ( _profIntent ) {
592                     case Inkscape::RENDERING_INTENT_RELATIVE_COLORIMETRIC:
593                         intent = INTENT_RELATIVE_COLORIMETRIC;
594                         break;
595                     case Inkscape::RENDERING_INTENT_SATURATION:
596                         intent = INTENT_SATURATION;
597                         break;
598                     case Inkscape::RENDERING_INTENT_ABSOLUTE_COLORIMETRIC:
599                         intent = INTENT_ABSOLUTE_COLORIMETRIC;
600                         break;
601                     case Inkscape::RENDERING_INTENT_PERCEPTUAL:
602                     case Inkscape::RENDERING_INTENT_UNKNOWN:
603                     case Inkscape::RENDERING_INTENT_AUTO:
604                     default:
605                         intent = INTENT_PERCEPTUAL;
606                 }
607                 _destProf = cmsCreate_sRGBProfile();
609                 _profChannelCount = _cmsChannelsOf( _profileSpace );
611                 DWORD inputFormat = TYPE_RGB_16;
612                 gchar const** names = 0;
613                 gchar const** tips = 0;
614                 getThings( _profileSpace, names, tips, _fooScales, inputFormat );
616                 _transf = cmsCreateTransform( _prof, inputFormat, _destProf, TYPE_RGBA_8, intent, 0 );
617                 if ( profChanged ) {
618                     for ( guint i = 0; i < _profChannelCount; i++ ) {
619                         gtk_label_set_text_with_mnemonic( GTK_LABEL(_fooLabel[i]), names[i]);
621                         gtk_tooltips_set_tip( _tt, _fooSlider[i], tips[i], NULL );
622                         gtk_tooltips_set_tip( _tt, _fooBtn[i], tips[i], NULL );
624                         sp_color_slider_set_colors( SP_COLOR_SLIDER(_fooSlider[i]),
625                                                     SPColor(0.0, 0.0, 0.0).toRGBA32(0xff),
626                                                     SPColor(0.5, 0.5, 0.5).toRGBA32(0xff),
627                                                     SPColor(1.0, 1.0, 1.0).toRGBA32(0xff) );
628 /*
629                         _fooAdj[i] = GTK_ADJUSTMENT( gtk_adjustment_new( val, 0.0, _fooScales[i],  step, page, page ) );
630                         gtk_signal_connect( GTK_OBJECT( _fooAdj[i] ), "value_changed", GTK_SIGNAL_FUNC( _adjustmentChanged ), _csel );
632                         sp_color_slider_set_adjustment( SP_COLOR_SLIDER(_fooSlider[i]), _fooAdj[i] );
633                         gtk_spin_button_set_adjustment( GTK_SPIN_BUTTON(_fooBtn[i]), _fooAdj[i] );
634                         gtk_spin_button_set_digits( GTK_SPIN_BUTTON(_fooBtn[i]), digits );
635 */
636                         gtk_widget_show( _fooLabel[i] );
637                         gtk_widget_show( _fooSlider[i] );
638                         gtk_widget_show( _fooBtn[i] );
639                         gtk_adjustment_set_value( _fooAdj[i], 0.0 );
640                         //gtk_adjustment_set_value( _fooAdj[i], val );
641                     }
642                     for ( guint i = _profChannelCount; i < _fooCount; i++ ) {
643                         gtk_widget_hide( _fooLabel[i] );
644                         gtk_widget_hide( _fooSlider[i] );
645                         gtk_widget_hide( _fooBtn[i] );
646                         gtk_adjustment_set_value( _fooAdj[i], 0.0 );
647                     }
648                 }
649             } else {
650                 // Give up for now on named colors
651                 _prof = 0;
652             }
653         }
654     }
656 #ifdef DEBUG_LCMS
657     g_message( "\\_________  %p::_setProfile()", this );
658 #endif // DEBUG_LCMS
660 #endif // ENABLE_LCMS
662 void ColorICCSelector::_updateSliders( gint ignore )
664 #ifdef ENABLE_LCMS
665     if ( _color.icc )
666     {
667         for ( guint i = 0; i < _profChannelCount; i++ ) {
668             gdouble val = 0.0;
669             if ( _color.icc->colors.size() > i ) {
670                 if ( _fooScales[i] == 256 ) {
671                     val = (_color.icc->colors[i] + 128.0) / static_cast<gdouble>(_fooScales[i]);
672                 } else {
673                     val = _color.icc->colors[i] / static_cast<gdouble>(_fooScales[i]);
674                 }
675             }
676             gtk_adjustment_set_value( _fooAdj[i], val );
677         }
679         if ( _transf ) {
680             for ( guint i = 0; i < _profChannelCount; i++ ) {
681                 if ( static_cast<gint>(i) != ignore ) {
682                     icUInt16Number* scratch = getScratch();
683                     icUInt16Number filler[4] = {0, 0, 0, 0};
684                     for ( guint j = 0; j < _profChannelCount; j++ ) {
685                         filler[j] = 0x0ffff * ColorScales::getScaled( _fooAdj[j] );
686                     }
688                     icUInt16Number* p = scratch;
689                     for ( guint x = 0; x < 1024; x++ ) {
690                         for ( guint j = 0; j < _profChannelCount; j++ ) {
691                             if ( j == i ) {
692                                 *p++ = x * 0x0ffff / 1024;
693                             } else {
694                                 *p++ = filler[j];
695                             }
696                         }
697                     }
699                     cmsDoTransform( _transf, scratch, _fooMap[i], 1024 );
700                     sp_color_slider_set_map( SP_COLOR_SLIDER(_fooSlider[i]), _fooMap[i] );
701                 }
702             }
703         }
704     }
705 #else
706     (void)ignore;
707 #endif // ENABLE_LCMS
709     guint32 start = _color.toRGBA32( 0x00 );
710     guint32 mid = _color.toRGBA32( 0x7f );
711     guint32 end = _color.toRGBA32( 0xff );
713     sp_color_slider_set_colors( SP_COLOR_SLIDER(_slider), start, mid, end );
718 void ColorICCSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorICCSelector *cs )
720 // // TODO check this. It looks questionable:
721 //     // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255  or 0..100
722 //     if (adjustment->value > 0.0 && adjustment->value < 1.0) {
723 //         gtk_adjustment_set_value( adjustment, floor ((adjustment->value) * adjustment->upper + 0.5) );
724 //     }
726 #ifdef DEBUG_LCMS
727     g_message( "/^^^^^^^^^  %p::_adjustmentChanged()", cs );
728 #endif // DEBUG_LCMS
730      ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base);
731      if (iccSelector->_updating) {
732          return;
733      }
735      iccSelector->_updating = TRUE;
737      gint match = -1;
739      SPColor newColor( iccSelector->_color );
740      gfloat scaled = ColorScales::getScaled( iccSelector->_adj );
741      if ( iccSelector->_adj == adjustment ) {
742 #ifdef DEBUG_LCMS
743          g_message("ALPHA");
744 #endif // DEBUG_LCMS
745      } else {
746 #if ENABLE_LCMS
747          for ( guint i = 0; i < iccSelector->_fooCount; i++ ) {
748              if ( iccSelector->_fooAdj[i] == adjustment ) {
749                  match = i;
750                  break;
751              }
752          }
753          if ( match >= 0 ) {
754 #ifdef DEBUG_LCMS
755              g_message(" channel %d", match );
756 #endif // DEBUG_LCMS
757          }
760          icUInt16Number tmp[4];
761          for ( guint i = 0; i < 4; i++ ) {
762              tmp[i] = ColorScales::getScaled( iccSelector->_fooAdj[i] ) * 0x0ffff;
763          }
764          guchar post[4] = {0,0,0,0};
766          cmsDoTransform( iccSelector->_transf, tmp, post, 1 );
768          SPColor other( SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255) );
769          other.icc = new SVGICCColor();
770          if ( iccSelector->_color.icc ) {
771              other.icc->colorProfile = iccSelector->_color.icc->colorProfile;
772          }
774          guint32 prior = iccSelector->_color.toRGBA32(255);
775          guint32 newer = other.toRGBA32(255);
777          if ( prior != newer ) {
778 #ifdef DEBUG_LCMS
779              g_message("Transformed color from 0x%08x to 0x%08x", prior, newer );
780              g_message("      ~~~~ FLIP");
781 #endif // DEBUG_LCMS
782              newColor = other;
783              newColor.icc->colors.clear();
784              for ( guint i = 0; i < iccSelector->_profChannelCount; i++ ) {
785                  gdouble val = ColorScales::getScaled( iccSelector->_fooAdj[i] );
786                  if ( iccSelector->_fooScales ) {
787                      val *= iccSelector->_fooScales[i];
788                      if ( iccSelector->_fooScales[i] == 256 ) {
789                          val -= 128;
790                      }
791                  }
792                  newColor.icc->colors.push_back( val );
793              }
794          }
795 #endif // ENABLE_LCMS
796      }
797      iccSelector->_updateInternals( newColor, scaled, iccSelector->_dragging );
798      iccSelector->_updateSliders( match );
800      iccSelector->_updating = FALSE;
801 #ifdef DEBUG_LCMS
802      g_message( "\\_________  %p::_adjustmentChanged()", cs );
803 #endif // DEBUG_LCMS
806 void ColorICCSelector::_sliderGrabbed( SPColorSlider *slider, SPColorICCSelector *cs )
808     (void)slider;
809     (void)cs;
810 //    ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base);
811 //     if (!iccSelector->_dragging) {
812 //         iccSelector->_dragging = TRUE;
813 //         iccSelector->_grabbed();
814 //         iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), iccSelector->_dragging );
815 //     }
818 void ColorICCSelector::_sliderReleased( SPColorSlider *slider, SPColorICCSelector *cs )
820     (void)slider;
821     (void)cs;
822 //     ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base);
823 //     if (iccSelector->_dragging) {
824 //         iccSelector->_dragging = FALSE;
825 //         iccSelector->_released();
826 //         iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), iccSelector->_dragging );
827 //     }
830 void ColorICCSelector::_sliderChanged( SPColorSlider *slider, SPColorICCSelector *cs )
832     (void)slider;
833     (void)cs;
834 #ifdef DEBUG_LCMS
835     g_message("Changed  %p and %p", slider, cs );
836 #endif // DEBUG_LCMS
837 //     ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base);
839 //     iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), iccSelector->_dragging );
843 /*
844   Local Variables:
845   mode:c++
846   c-file-style:"stroustrup"
847   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
848   indent-tabs-mode:nil
849   fill-column:99
850   End:
851 */
852 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :