[gimp] libgimpwidgets: add gimp_preview_area_set_color_config()
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] libgimpwidgets: add gimp_preview_area_set_color_config()
- Date: Tue, 24 May 2016 19:46:09 +0000 (UTC)
commit 9c99d61febd808925bf9152b09f7344ad91c89ea
Author: Michael Natterer <mitch gimp org>
Date: Tue May 24 21:43:20 2016 +0200
libgimpwidgets: add gimp_preview_area_set_color_config()
If a config is set, apply its settings when drawing the preview's
pixels. This is preparation for fixing:
Bug 467930 - color selectors are not color managed
Bug 556608 - Monitor color profile is not applied to filter preview
libgimpwidgets/gimppreviewarea.c | 222 ++++++++++++++++++++++++++++++++------
libgimpwidgets/gimppreviewarea.h | 119 +++++++++++----------
libgimpwidgets/gimpwidgets.def | 1 +
3 files changed, 252 insertions(+), 90 deletions(-)
---
diff --git a/libgimpwidgets/gimppreviewarea.c b/libgimpwidgets/gimppreviewarea.c
index e3021d6..496fa8c 100644
--- a/libgimpwidgets/gimppreviewarea.c
+++ b/libgimpwidgets/gimppreviewarea.c
@@ -19,14 +19,19 @@
#include "config.h"
#include <string.h>
+#include <lcms2.h>
+#include <gegl.h>
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+#include "libgimpcolor/gimpcolor.h"
#include "gimpwidgetstypes.h"
#include "gimppreviewarea.h"
+#include "gimpwidgetsutils.h"
#include "libgimp/libgimp-intl.h"
@@ -57,27 +62,48 @@ enum
(((area)->offset_x + (col)) & size)) ? dark : light)
-static void gimp_preview_area_finalize (GObject *object);
-static void gimp_preview_area_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_preview_area_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
+typedef struct _GimpPreviewAreaPrivate GimpPreviewAreaPrivate;
-static void gimp_preview_area_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static gboolean gimp_preview_area_expose (GtkWidget *widget,
- GdkEventExpose *event);
+struct _GimpPreviewAreaPrivate
+{
+ GimpColorConfig *config;
+ GimpColorTransform transform;
+};
+
+#define GET_PRIVATE(obj) \
+ G_TYPE_INSTANCE_GET_PRIVATE (obj, \
+ GIMP_TYPE_PREVIEW_AREA, \
+ GimpPreviewAreaPrivate)
+
+
+static void gimp_preview_area_dispose (GObject *object);
+static void gimp_preview_area_finalize (GObject *object);
+static void gimp_preview_area_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_preview_area_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
-static void gimp_preview_area_queue_draw (GimpPreviewArea *area,
- gint x,
- gint y,
- gint width,
- gint height);
-static gint gimp_preview_area_image_type_bytes (GimpImageType type);
+static void gimp_preview_area_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gboolean gimp_preview_area_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+
+static void gimp_preview_area_queue_draw (GimpPreviewArea *area,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
+static gint gimp_preview_area_image_type_bytes (GimpImageType type);
+
+static void gimp_preview_area_config_notify (GimpColorConfig *config,
+ const GParamSpec *pspec,
+ GimpPreviewArea *area);
+
+static void gimp_preview_area_create_transform (GimpPreviewArea *area);
G_DEFINE_TYPE (GimpPreviewArea, gimp_preview_area, GTK_TYPE_DRAWING_AREA)
@@ -91,6 +117,7 @@ gimp_preview_area_class_init (GimpPreviewAreaClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ object_class->dispose = gimp_preview_area_dispose;
object_class->finalize = gimp_preview_area_finalize;
object_class->set_property = gimp_preview_area_set_property;
object_class->get_property = gimp_preview_area_get_property;
@@ -111,6 +138,8 @@ gimp_preview_area_class_init (GimpPreviewAreaClass *klass)
GIMP_TYPE_CHECK_TYPE,
DEFAULT_CHECK_TYPE,
GIMP_PARAM_READWRITE));
+
+ g_type_class_add_private (object_class, sizeof (GimpPreviewAreaPrivate));
}
static void
@@ -130,6 +159,16 @@ gimp_preview_area_init (GimpPreviewArea *area)
}
static void
+gimp_preview_area_dispose (GObject *object)
+{
+ GimpPreviewArea *area = GIMP_PREVIEW_AREA (object);
+
+ gimp_preview_area_set_color_config (area, NULL);
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
gimp_preview_area_finalize (GObject *object)
{
GimpPreviewArea *area = GIMP_PREVIEW_AREA (object);
@@ -139,6 +178,7 @@ gimp_preview_area_finalize (GObject *object)
g_free (area->buf);
area->buf = NULL;
}
+
if (area->colormap)
{
g_free (area->colormap);
@@ -229,11 +269,12 @@ static gboolean
gimp_preview_area_expose (GtkWidget *widget,
GdkEventExpose *event)
{
- GimpPreviewArea *area = GIMP_PREVIEW_AREA (widget);
- GtkAllocation allocation;
- GdkPixbuf *pixbuf;
- GdkRectangle rect;
- cairo_t *cr;
+ GimpPreviewArea *area = GIMP_PREVIEW_AREA (widget);
+ GimpPreviewAreaPrivate *priv = GET_PRIVATE (area);
+ GtkAllocation allocation;
+ GdkPixbuf *pixbuf;
+ GdkRectangle rect;
+ cairo_t *cr;
if (! area->buf)
return FALSE;
@@ -245,14 +286,46 @@ gimp_preview_area_expose (GtkWidget *widget,
rect.width = area->width;
rect.height = area->height;
- pixbuf = gdk_pixbuf_new_from_data (area->buf,
- GDK_COLORSPACE_RGB,
- FALSE,
- 8,
- rect.width,
- rect.height,
- area->rowstride,
- NULL, NULL);
+ if (! priv->transform)
+ gimp_preview_area_create_transform (area);
+
+ if (priv->transform)
+ {
+ gint rowstride = ((area->width * 3) + 3) & ~3;
+ guchar *buf = g_new (guchar, rowstride * area->height);
+ guchar *src = area->buf;
+ guchar *dest = buf;
+ gint i;
+
+ for (i = 0; i < area->height; i++)
+ {
+ cmsDoTransform (priv->transform, src, dest, area->width);
+
+ src += area->rowstride;
+ dest += rowstride;
+ }
+
+ pixbuf = gdk_pixbuf_new_from_data (buf,
+ GDK_COLORSPACE_RGB,
+ FALSE,
+ 8,
+ rect.width,
+ rect.height,
+ rowstride,
+ (GdkPixbufDestroyNotify) g_free, NULL);
+ }
+ else
+ {
+ pixbuf = gdk_pixbuf_new_from_data (area->buf,
+ GDK_COLORSPACE_RGB,
+ FALSE,
+ 8,
+ rect.width,
+ rect.height,
+ area->rowstride,
+ NULL, NULL);
+ }
+
cr = gdk_cairo_create (gtk_widget_get_window (widget));
gdk_cairo_region (cr, event->region);
@@ -310,6 +383,45 @@ gimp_preview_area_image_type_bytes (GimpImageType type)
}
}
+static void
+gimp_preview_area_config_notify (GimpColorConfig *config,
+ const GParamSpec *pspec,
+ GimpPreviewArea *area)
+{
+ GimpPreviewAreaPrivate *priv = GET_PRIVATE (area);
+
+ if (priv->transform)
+ {
+ cmsDeleteTransform (priv->transform);
+ priv->transform = NULL;
+ }
+
+ gtk_widget_queue_draw (GTK_WIDGET (area));
+}
+
+static void
+gimp_preview_area_create_transform (GimpPreviewArea *area)
+{
+ GimpPreviewAreaPrivate *priv = GET_PRIVATE (area);
+
+ if (priv->config)
+ {
+ static GimpColorProfile *profile = NULL;
+
+ const Babl *format = babl_format ("R'G'B' u8");
+
+ if (G_UNLIKELY (! profile))
+ profile = gimp_color_profile_new_rgb_srgb ();
+
+ priv->transform = gimp_widget_get_color_transform (GTK_WIDGET (area),
+ priv->config,
+ profile,
+ &format,
+ &format);
+ }
+}
+
+
/**
* gimp_preview_area_new:
*
@@ -1665,6 +1777,52 @@ gimp_preview_area_set_colormap (GimpPreviewArea *area,
}
/**
+ * gimp_preview_area_set_color_config:
+ * @area: a #GimpPreviewArea widget.
+ * @config: a #GimpColorConfig object.
+ *
+ * Sets the color management configuration to use with this preview area.
+ *
+ * Since: 2.10
+ */
+void
+gimp_preview_area_set_color_config (GimpPreviewArea *area,
+ GimpColorConfig *config)
+{
+ GimpPreviewAreaPrivate *priv;
+
+ g_return_if_fail (GIMP_IS_PREVIEW_AREA (area));
+ g_return_if_fail (config == NULL || GIMP_IS_COLOR_CONFIG (config));
+
+ priv = GET_PRIVATE (area);
+
+ if (priv->config)
+ {
+ g_signal_handlers_disconnect_by_func (priv->config,
+ gimp_preview_area_config_notify,
+ area);
+ g_object_unref (priv->config);
+
+ if (priv->transform)
+ {
+ cmsDeleteTransform (priv->transform);
+ priv->transform = NULL;
+ }
+ }
+
+ priv->config = config;
+
+ if (priv->config)
+ {
+ g_object_ref (priv->config);
+
+ g_signal_connect (priv->config, "notify",
+ G_CALLBACK (gimp_preview_area_config_notify),
+ area);
+ }
+}
+
+/**
* gimp_preview_area_set_max_size:
* @area: a #GimpPreviewArea widget
* @width: the maximum width in pixels or -1 to unset the limit
diff --git a/libgimpwidgets/gimppreviewarea.h b/libgimpwidgets/gimppreviewarea.h
index 4d6b440..256a9fb 100644
--- a/libgimpwidgets/gimppreviewarea.h
+++ b/libgimpwidgets/gimppreviewarea.h
@@ -65,64 +65,67 @@ struct _GimpPreviewAreaClass
};
-GType gimp_preview_area_get_type (void) G_GNUC_CONST;
-
-GtkWidget * gimp_preview_area_new (void);
-
-void gimp_preview_area_draw (GimpPreviewArea *area,
- gint x,
- gint y,
- gint width,
- gint height,
- GimpImageType type,
- const guchar *buf,
- gint rowstride);
-void gimp_preview_area_blend (GimpPreviewArea *area,
- gint x,
- gint y,
- gint width,
- gint height,
- GimpImageType type,
- const guchar *buf1,
- gint rowstride1,
- const guchar *buf2,
- gint rowstride2,
- guchar opacity);
-void gimp_preview_area_mask (GimpPreviewArea *area,
- gint x,
- gint y,
- gint width,
- gint height,
- GimpImageType type,
- const guchar *buf1,
- gint rowstride1,
- const guchar *buf2,
- gint rowstride2,
- const guchar *mask,
- gint rowstride_mask);
-void gimp_preview_area_fill (GimpPreviewArea *area,
- gint x,
- gint y,
- gint width,
- gint height,
- guchar red,
- guchar green,
- guchar blue);
-
-void gimp_preview_area_set_offsets (GimpPreviewArea *area,
- gint x,
- gint y);
-
-void gimp_preview_area_set_colormap (GimpPreviewArea *area,
- const guchar *colormap,
- gint num_colors);
-
-void gimp_preview_area_set_max_size (GimpPreviewArea *area,
- gint width,
- gint height);
-
-void gimp_preview_area_menu_popup (GimpPreviewArea *area,
- GdkEventButton *event);
+GType gimp_preview_area_get_type (void) G_GNUC_CONST;
+
+GtkWidget * gimp_preview_area_new (void);
+
+void gimp_preview_area_draw (GimpPreviewArea *area,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GimpImageType type,
+ const guchar *buf,
+ gint rowstride);
+void gimp_preview_area_blend (GimpPreviewArea *area,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GimpImageType type,
+ const guchar *buf1,
+ gint rowstride1,
+ const guchar *buf2,
+ gint rowstride2,
+ guchar opacity);
+void gimp_preview_area_mask (GimpPreviewArea *area,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GimpImageType type,
+ const guchar *buf1,
+ gint rowstride1,
+ const guchar *buf2,
+ gint rowstride2,
+ const guchar *mask,
+ gint rowstride_mask);
+void gimp_preview_area_fill (GimpPreviewArea *area,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ guchar red,
+ guchar green,
+ guchar blue);
+
+void gimp_preview_area_set_offsets (GimpPreviewArea *area,
+ gint x,
+ gint y);
+
+void gimp_preview_area_set_colormap (GimpPreviewArea *area,
+ const guchar *colormap,
+ gint num_colors);
+
+void gimp_preview_area_set_color_config (GimpPreviewArea *area,
+ GimpColorConfig *config);
+
+void gimp_preview_area_set_max_size (GimpPreviewArea *area,
+ gint width,
+ gint height);
+
+void gimp_preview_area_menu_popup (GimpPreviewArea *area,
+ GdkEventButton *event);
G_END_DECLS
diff --git a/libgimpwidgets/gimpwidgets.def b/libgimpwidgets/gimpwidgets.def
index 50cdae4..5eb7d03 100644
--- a/libgimpwidgets/gimpwidgets.def
+++ b/libgimpwidgets/gimpwidgets.def
@@ -276,6 +276,7 @@ EXPORTS
gimp_preview_area_mask
gimp_preview_area_menu_popup
gimp_preview_area_new
+ gimp_preview_area_set_color_config
gimp_preview_area_set_colormap
gimp_preview_area_set_max_size
gimp_preview_area_set_offsets
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]