From 95f1c87a21d171a48aab671a3567847702ff72e8 Mon Sep 17 00:00:00 2001 From: joncruz Date: Tue, 25 Sep 2007 02:54:32 +0000 Subject: [PATCH] Initial support for icc color selection including CMYK --- src/color.cpp | 34 +- src/color.h | 3 + src/desktop-style.cpp | 21 +- src/dialogs/fill-style.cpp | 6 +- src/dialogs/stroke-style.cpp | 5 +- src/style.cpp | 21 +- src/style.h | 1 - src/widgets/Makefile_insert | 2 + src/widgets/paint-selector.cpp | 30 +- src/widgets/sp-color-gtkselector.cpp | 8 +- src/widgets/sp-color-icc-selector.cpp | 776 ++++++++++++++++++++++++++ src/widgets/sp-color-icc-selector.h | 115 ++++ src/widgets/sp-color-notebook.cpp | 7 +- src/widgets/sp-color-selector.cpp | 25 +- src/widgets/sp-color-slider.cpp | 3 + 15 files changed, 1010 insertions(+), 47 deletions(-) create mode 100644 src/widgets/sp-color-icc-selector.cpp create mode 100644 src/widgets/sp-color-icc-selector.h diff --git a/src/color.cpp b/src/color.cpp index 8dc4c8657..6b2281f26 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -17,6 +17,12 @@ #include #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(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::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 diff --git a/src/color.h b/src/color.h index e93943609..4fcffad8e 100644 --- a/src/color.h +++ b/src/color.h @@ -16,6 +16,7 @@ */ #include +#include /* 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]; diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index b1dca7f17..236130173 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -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; diff --git a/src/dialogs/fill-style.cpp b/src/dialogs/fill-style.cpp index 1dfaea546..3c0620feb 100644 --- a/src/dialogs/fill-style.cpp +++ b/src/dialogs/fill-style.cpp @@ -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); diff --git a/src/dialogs/stroke-style.cpp b/src/dialogs/stroke-style.cpp index 9dc7131fc..08f3d9031 100644 --- a/src/dialogs/stroke-style.cpp +++ b/src/dialogs/stroke-style.cpp @@ -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; diff --git a/src/style.cpp b/src/style.cpp index b817ce083..e0cd1e947 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -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::const_iterator i(paint->value.iccColor->colors.begin()), - iEnd(paint->value.iccColor->colors.end()); + css << "icc-color(" << paint->value.color.icc->colorProfile; + for (vector::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; } diff --git a/src/style.h b/src/style.h index 9b2d2878a..6e62187bc 100644 --- a/src/style.h +++ b/src/style.h @@ -156,7 +156,6 @@ struct SPIPaint { struct { SPPaintServerReference *href; SPColor color; - SVGICCColor *iccColor; } value; diff --git a/src/widgets/Makefile_insert b/src/widgets/Makefile_insert index 854ca9122..d46037157 100644 --- a/src/widgets/Makefile_insert +++ b/src/widgets/Makefile_insert @@ -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 \ diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index 3c103afb0..56daf948d 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -46,6 +46,10 @@ #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():"") ); +#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); diff --git a/src/widgets/sp-color-gtkselector.cpp b/src/widgets/sp-color-gtkselector.cpp index b583903e3..9a16ab059 100644 --- a/src/widgets/sp-color-gtkselector.cpp +++ b/src/widgets/sp-color-gtkselector.cpp @@ -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 index 000000000..23294d61e --- /dev/null +++ b/src/widgets/sp-color-icc-selector.cpp @@ -0,0 +1,776 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include +#include +#include +#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 +#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(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(_fooScales[i]) / 100.0; + gdouble page = static_cast(_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(): "" ) + ); +#endif // DEBUG_LCMS + +#ifdef DEBUG_LCMS + g_message("FLIPPIES!!!! %p '%s'", color.icc, (color.icc?color.icc->colorProfile.c_str():"")); +#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() : "") + ); +#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(_fooScales[i]) / 100.0; + gdouble page = static_cast(_fooScales[i]) / 10.0; + gint digits = (step > 0.9) ? 0 : 2; +*/ + gdouble val = (_color.icc->colors.size() > i) ? (_color.icc->colors[i] / static_cast(_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 index 000000000..e29d167f2 --- /dev/null +++ b/src/widgets/sp-color-icc-selector.h @@ -0,0 +1,115 @@ +#ifndef __SP_COLOR_ICC_SELECTOR_H__ +#define __SP_COLOR_ICC_SELECTOR_H__ + +#include +#include +#include + +#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 : diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index 60617b849..44d6b3799 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -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. */ diff --git a/src/widgets/sp-color-selector.cpp b/src/widgets/sp-color-selector.cpp index ec80eff3e..052996247 100644 --- a/src/widgets/sp-color-selector.cpp +++ b/src/widgets/sp-color-selector.cpp @@ -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():""), 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():""), 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():""), 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():""), FOO_NAME(_csel)); #endif gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[_held ? CHANGED : DRAGGED]); } diff --git a/src/widgets/sp-color-slider.cpp b/src/widgets/sp-color-slider.cpp index 76ef13a8d..b3c775c37 100644 --- a/src/widgets/sp-color-slider.cpp +++ b/src/widgets/sp-color-slider.cpp @@ -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; -- 2.30.2