1
/* GIMP CMYK ColorSelector using littleCMS
2
* Copyright (C) 2006 Sven Neumann <sven@gimp.org>
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
#include <glib.h> /* lcms.h uses the "inline" keyword */
23
#ifdef HAVE_LCMS_LCMS_H
24
#include <lcms/lcms.h>
31
#include "libgimpcolor/gimpcolor.h"
32
#include "libgimpconfig/gimpconfig.h"
33
#include "libgimpmodule/gimpmodule.h"
34
#include "libgimpwidgets/gimpwidgets.h"
36
#include "libgimp/libgimp-intl.h"
39
/* definitions and variables */
41
#define COLORSEL_TYPE_CMYK (colorsel_cmyk_type)
42
#define COLORSEL_CMYK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COLORSEL_TYPE_CMYK, ColorselCmyk))
43
#define COLORSEL_CMYK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COLORSEL_TYPE_CMYK, ColorselCmykClass))
44
#define COLORSEL_IS_CMYK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COLORSEL_TYPE_CMYK))
45
#define COLORSEL_IS_CMYK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COLORSEL_TYPE_CMYK))
48
typedef struct _ColorselCmyk ColorselCmyk;
49
typedef struct _ColorselCmykClass ColorselCmykClass;
53
GimpColorSelector parent_instance;
55
GimpColorConfig *config;
56
cmsHTRANSFORM rgb2cmyk;
57
cmsHTRANSFORM cmyk2rgb;
60
GtkAdjustment *adj[4];
61
GtkWidget *name_label;
63
gboolean in_destruction;
66
struct _ColorselCmykClass
68
GimpColorSelectorClass parent_class;
72
static GType colorsel_cmyk_get_type (GTypeModule *module);
73
static void colorsel_cmyk_class_init (ColorselCmykClass *klass);
74
static void colorsel_cmyk_init (ColorselCmyk *cmyk);
75
static void colorsel_cmyk_dispose (GObject *object);
77
static void colorsel_cmyk_set_color (GimpColorSelector *selector,
80
static void colorsel_cmyk_set_config (GimpColorSelector *selector,
81
GimpColorConfig *config);
83
static void colorsel_cmyk_adj_update (GtkAdjustment *adj,
84
ColorselCmyk *module);
85
static void colorsel_cmyk_config_changed (ColorselCmyk *module);
88
static const GimpModuleInfo colorsel_cmyk_info =
90
GIMP_MODULE_ABI_VERSION,
91
N_("CMYK color selector (using color profile)"),
92
"Sven Neumann <sven@gimp.org>",
94
"(c) 2006, released under the GPL",
98
static GType colorsel_cmyk_type = 0;
99
static GObjectClass *parent_class = NULL;
102
G_MODULE_EXPORT const GimpModuleInfo *
103
gimp_module_query (GTypeModule *module)
105
return &colorsel_cmyk_info;
108
G_MODULE_EXPORT gboolean
109
gimp_module_register (GTypeModule *module)
111
colorsel_cmyk_get_type (module);
117
colorsel_cmyk_get_type (GTypeModule *module)
119
if (! colorsel_cmyk_type)
121
const GTypeInfo select_info =
123
sizeof (ColorselCmykClass),
124
(GBaseInitFunc) NULL,
125
(GBaseFinalizeFunc) NULL,
126
(GClassInitFunc) colorsel_cmyk_class_init,
127
NULL, /* class_finalize */
128
NULL, /* class_data */
129
sizeof (ColorselCmyk),
131
(GInstanceInitFunc) colorsel_cmyk_init,
135
g_type_module_register_type (module,
136
GIMP_TYPE_COLOR_SELECTOR,
141
return colorsel_cmyk_type;
145
colorsel_cmyk_class_init (ColorselCmykClass *klass)
147
GObjectClass *object_class = G_OBJECT_CLASS (klass);
148
GimpColorSelectorClass *selector_class = GIMP_COLOR_SELECTOR_CLASS (klass);
150
parent_class = g_type_class_peek_parent (klass);
152
object_class->dispose = colorsel_cmyk_dispose;
154
selector_class->name = _("CMYK");
155
selector_class->help_id = "gimp-colorselector-cmyk";
156
selector_class->stock_id = GTK_STOCK_PRINT; /* FIXME */
157
selector_class->set_color = colorsel_cmyk_set_color;
158
selector_class->set_config = colorsel_cmyk_set_config;
162
colorsel_cmyk_init (ColorselCmyk *module)
168
static const gchar * const cmyk_labels[] =
179
static const gchar * const cmyk_tips[] =
187
module->config = NULL;
188
module->rgb2cmyk = NULL;
189
module->cmyk2rgb = NULL;
191
gtk_box_set_spacing (GTK_BOX (module), 6);
193
table = gtk_table_new (4, 4, FALSE);
195
gtk_table_set_row_spacings (GTK_TABLE (table), 1);
196
gtk_table_set_col_spacings (GTK_TABLE (table), 2);
197
gtk_table_set_col_spacing (GTK_TABLE (table), 0, 0);
199
gtk_box_pack_start (GTK_BOX (module), table, FALSE, FALSE, 0);
200
gtk_widget_show (table);
202
for (i = 0; i < 4; i++)
204
adj = gimp_scale_entry_new (GTK_TABLE (table), 1, i,
205
gettext (cmyk_labels[i]),
212
gettext (cmyk_tips[i]),
215
g_signal_connect (adj, "value-changed",
216
G_CALLBACK (colorsel_cmyk_adj_update),
219
module->adj[i] = GTK_ADJUSTMENT (adj);
222
module->name_label = gtk_label_new (NULL);
223
gtk_misc_set_alignment (GTK_MISC (module->name_label), 0.0, 0.5);
224
gimp_label_set_attributes (GTK_LABEL (module->name_label),
225
PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
226
PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
228
gtk_box_pack_start (GTK_BOX (module), module->name_label, FALSE, FALSE, 0);
229
gtk_widget_show (module->name_label);
233
colorsel_cmyk_dispose (GObject *object)
235
ColorselCmyk *module = COLORSEL_CMYK (object);
237
module->in_destruction = TRUE;
239
colorsel_cmyk_set_config (GIMP_COLOR_SELECTOR (object), NULL);
241
G_OBJECT_CLASS (parent_class)->dispose (object);
245
colorsel_cmyk_set_color (GimpColorSelector *selector,
249
ColorselCmyk *module = COLORSEL_CMYK (selector);
251
if (module->rgb2cmyk)
253
gdouble rgb_values[3];
254
gdouble cmyk_values[4];
256
rgb_values[0] = rgb->r;
257
rgb_values[1] = rgb->g;
258
rgb_values[2] = rgb->b;
260
cmsDoTransform (module->rgb2cmyk, rgb_values, cmyk_values, 1);
262
module->cmyk.c = cmyk_values[0] / 100.0;
263
module->cmyk.m = cmyk_values[1] / 100.0;
264
module->cmyk.y = cmyk_values[2] / 100.0;
265
module->cmyk.k = cmyk_values[3] / 100.0;
269
gimp_rgb_to_cmyk (rgb, 1.0, &module->cmyk);
272
gtk_adjustment_set_value (module->adj[0], module->cmyk.c * 100.0);
273
gtk_adjustment_set_value (module->adj[1], module->cmyk.m * 100.0);
274
gtk_adjustment_set_value (module->adj[2], module->cmyk.y * 100.0);
275
gtk_adjustment_set_value (module->adj[3], module->cmyk.k * 100.0);
279
colorsel_cmyk_set_config (GimpColorSelector *selector,
280
GimpColorConfig *config)
282
ColorselCmyk *module = COLORSEL_CMYK (selector);
284
if (config == module->config)
289
g_signal_handlers_disconnect_by_func (module->config,
290
G_CALLBACK (colorsel_cmyk_config_changed),
292
g_object_unref (module->config);
295
module->config = config;
299
g_object_ref (module->config);
300
g_signal_connect_swapped (module->config, "notify",
301
G_CALLBACK (colorsel_cmyk_config_changed),
305
colorsel_cmyk_config_changed (module);
309
colorsel_cmyk_adj_update (GtkAdjustment *adj,
310
ColorselCmyk *module)
312
GimpColorSelector *selector = GIMP_COLOR_SELECTOR (module);
315
for (i = 0; i < 4; i++)
316
if (module->adj[i] == adj)
322
module->cmyk.c = adj->value / 100.0;
325
module->cmyk.m = adj->value / 100.0;
328
module->cmyk.y = adj->value / 100.0;
331
module->cmyk.k = adj->value / 100.0;
337
if (module->cmyk2rgb)
339
gdouble cmyk_values[4];
340
gdouble rgb_values[3];
342
cmyk_values[0] = module->cmyk.c * 100.0;
343
cmyk_values[1] = module->cmyk.m * 100.0;
344
cmyk_values[2] = module->cmyk.y * 100.0;
345
cmyk_values[3] = module->cmyk.k * 100.0;
347
cmsDoTransform (module->cmyk2rgb, cmyk_values, rgb_values, 1);
349
selector->rgb.r = rgb_values[0];
350
selector->rgb.g = rgb_values[1];
351
selector->rgb.b = rgb_values[2];
355
gimp_cmyk_to_rgb (&module->cmyk, &selector->rgb);
358
gimp_rgb_to_hsv (&selector->rgb, &selector->hsv);
360
gimp_color_selector_color_changed (selector);
364
color_config_get_rgb_profile (GimpColorConfig *config)
366
cmsHPROFILE profile = NULL;
368
if (config->rgb_profile)
369
profile = cmsOpenProfileFromFile (config->rgb_profile, "r");
371
return profile ? profile : cmsCreate_sRGBProfile ();
375
colorsel_cmyk_config_changed (ColorselCmyk *module)
377
GimpColorSelector *selector = GIMP_COLOR_SELECTOR (module);
378
GimpColorConfig *config = module->config;
379
cmsHPROFILE rgb_profile;
380
cmsHPROFILE cmyk_profile;
384
if (module->rgb2cmyk)
386
cmsDeleteTransform (module->rgb2cmyk);
387
module->rgb2cmyk = NULL;
390
if (module->cmyk2rgb)
392
cmsDeleteTransform (module->cmyk2rgb);
393
module->cmyk2rgb = NULL;
396
gtk_label_set_text (GTK_LABEL (module->name_label), _("Profile: (none)"));
398
if (! config || config->mode == GIMP_COLOR_MANAGEMENT_OFF)
401
if (! config->cmyk_profile ||
402
! (cmyk_profile = cmsOpenProfileFromFile (config->cmyk_profile, "r")))
405
name = cmsTakeProductName (cmyk_profile);
406
if (! g_utf8_validate (name, -1, NULL))
407
name = _("(invalid UTF-8 string)");
409
text = g_strdup_printf (_("Profile: %s"), name);
410
gtk_label_set_text (GTK_LABEL (module->name_label), text);
413
rgb_profile = color_config_get_rgb_profile (config);
415
module->rgb2cmyk = cmsCreateTransform (rgb_profile, TYPE_RGB_DBL,
416
cmyk_profile, TYPE_CMYK_DBL,
419
module->cmyk2rgb = cmsCreateTransform (cmyk_profile, TYPE_CMYK_DBL,
420
rgb_profile, TYPE_RGB_DBL,
424
cmsCloseProfile (rgb_profile);
425
cmsCloseProfile (cmyk_profile);
428
if (! module->in_destruction)
429
gimp_color_selector_set_color (selector, &selector->rgb, &selector->hsv);