libgimpwidgets: GimpColorArea made final.

This commit is contained in:
Jehan 2024-10-16 21:17:29 +02:00
parent 925faf83ac
commit ba3f0c73a4
2 changed files with 122 additions and 184 deletions

View file

@ -66,8 +66,10 @@ enum
}; };
typedef struct _GimpColorAreaPrivate struct _GimpColorArea
{ {
GtkDrawingArea parent_instance;
GimpColorConfig *config; GimpColorConfig *config;
GimpColorTransform *transform; GimpColorTransform *transform;
@ -82,7 +84,7 @@ typedef struct _GimpColorAreaPrivate
guint needs_render : 1; guint needs_render : 1;
gboolean out_of_gamut; gboolean out_of_gamut;
} GimpColorAreaPrivate; };
static void gimp_color_area_dispose (GObject *object); static void gimp_color_area_dispose (GObject *object);
@ -130,8 +132,7 @@ static void gimp_color_area_create_transform (GimpColorArea *area);
static void gimp_color_area_destroy_transform (GimpColorArea *area); static void gimp_color_area_destroy_transform (GimpColorArea *area);
G_DEFINE_TYPE_WITH_PRIVATE (GimpColorArea, gimp_color_area, G_DEFINE_TYPE (GimpColorArea, gimp_color_area, GTK_TYPE_DRAWING_AREA)
GTK_TYPE_DRAWING_AREA)
#define parent_class gimp_color_area_parent_class #define parent_class gimp_color_area_parent_class
@ -150,7 +151,7 @@ gimp_color_area_class_init (GimpColorAreaClass *klass)
g_signal_new ("color-changed", g_signal_new ("color-changed",
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpColorAreaClass, color_changed), 0,
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
@ -167,8 +168,6 @@ gimp_color_area_class_init (GimpColorAreaClass *klass)
widget_class->drag_data_received = gimp_color_area_drag_data_received; widget_class->drag_data_received = gimp_color_area_drag_data_received;
widget_class->drag_data_get = gimp_color_area_drag_data_get; widget_class->drag_data_get = gimp_color_area_drag_data_get;
klass->color_changed = NULL;
babl_init (); babl_init ();
/** /**
@ -232,16 +231,12 @@ gimp_color_area_class_init (GimpColorAreaClass *klass)
static void static void
gimp_color_area_init (GimpColorArea *area) gimp_color_area_init (GimpColorArea *area)
{ {
GimpColorAreaPrivate *priv; area->buf = NULL;
area->width = 0;
priv = gimp_color_area_get_instance_private (area); area->height = 0;
area->rowstride = 0;
priv->buf = NULL; area->draw_border = FALSE;
priv->width = 0; area->color = gegl_color_new ("black");
priv->height = 0;
priv->rowstride = 0;
priv->draw_border = FALSE;
priv->color = gegl_color_new ("black");
gtk_drag_dest_set (GTK_WIDGET (area), gtk_drag_dest_set (GTK_WIDGET (area),
GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_HIGHLIGHT |
@ -269,10 +264,9 @@ static void
gimp_color_area_finalize (GObject *object) gimp_color_area_finalize (GObject *object)
{ {
GimpColorArea *area = GIMP_COLOR_AREA (object); GimpColorArea *area = GIMP_COLOR_AREA (object);
GimpColorAreaPrivate *priv = gimp_color_area_get_instance_private (area);
g_clear_pointer (&priv->buf, g_free); g_clear_pointer (&area->buf, g_free);
g_clear_object (&priv->color); g_clear_object (&area->color);
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
@ -284,20 +278,19 @@ gimp_color_area_get_property (GObject *object,
GParamSpec *pspec) GParamSpec *pspec)
{ {
GimpColorArea *area = GIMP_COLOR_AREA (object); GimpColorArea *area = GIMP_COLOR_AREA (object);
GimpColorAreaPrivate *priv = gimp_color_area_get_instance_private (area);
switch (property_id) switch (property_id)
{ {
case PROP_COLOR: case PROP_COLOR:
g_value_set_object (value, priv->color); g_value_set_object (value, area->color);
break; break;
case PROP_TYPE: case PROP_TYPE:
g_value_set_enum (value, priv->type); g_value_set_enum (value, area->type);
break; break;
case PROP_DRAW_BORDER: case PROP_DRAW_BORDER:
g_value_set_boolean (value, priv->draw_border); g_value_set_boolean (value, area->draw_border);
break; break;
default: default:
@ -353,22 +346,21 @@ gimp_color_area_size_allocate (GtkWidget *widget,
GtkAllocation *allocation) GtkAllocation *allocation)
{ {
GimpColorArea *area = GIMP_COLOR_AREA (widget); GimpColorArea *area = GIMP_COLOR_AREA (widget);
GimpColorAreaPrivate *priv = gimp_color_area_get_instance_private (area);
GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
if (allocation->width != priv->width || if (allocation->width != area->width ||
allocation->height != priv->height) allocation->height != area->height)
{ {
priv->width = allocation->width; area->width = allocation->width;
priv->height = allocation->height; area->height = allocation->height;
priv->rowstride = priv->width * 4 + 4; area->rowstride = area->width * 4 + 4;
g_free (priv->buf); g_free (area->buf);
priv->buf = g_new (guchar, priv->rowstride * priv->height); area->buf = g_new (guchar, area->rowstride * area->height);
priv->needs_render = TRUE; area->needs_render = TRUE;
} }
} }
@ -377,54 +369,53 @@ gimp_color_area_draw (GtkWidget *widget,
cairo_t *cr) cairo_t *cr)
{ {
GimpColorArea *area = GIMP_COLOR_AREA (widget); GimpColorArea *area = GIMP_COLOR_AREA (widget);
GimpColorAreaPrivate *priv = gimp_color_area_get_instance_private (area);
GtkStyleContext *context = gtk_widget_get_style_context (widget); GtkStyleContext *context = gtk_widget_get_style_context (widget);
cairo_surface_t *buffer; cairo_surface_t *buffer;
gboolean oog = priv->out_of_gamut; gboolean oog = area->out_of_gamut;
if (! priv->buf) if (! area->buf)
return FALSE; return FALSE;
if (priv->needs_render) if (area->needs_render)
gimp_color_area_render (area); gimp_color_area_render (area);
if (! priv->transform) if (! area->transform)
gimp_color_area_create_transform (area); gimp_color_area_create_transform (area);
if (priv->transform) if (area->transform)
{ {
const Babl *format = babl_format ("cairo-RGB24"); const Babl *format = babl_format ("cairo-RGB24");
guchar *buf = g_new (guchar, priv->rowstride * priv->height); guchar *buf = g_new (guchar, area->rowstride * area->height);
guchar *src = priv->buf; guchar *src = area->buf;
guchar *dest = buf; guchar *dest = buf;
guint i; guint i;
for (i = 0; i < priv->height; i++) for (i = 0; i < area->height; i++)
{ {
gimp_color_transform_process_pixels (priv->transform, gimp_color_transform_process_pixels (area->transform,
format, src, format, src,
format, dest, format, dest,
priv->width); area->width);
src += priv->rowstride; src += area->rowstride;
dest += priv->rowstride; dest += area->rowstride;
} }
buffer = cairo_image_surface_create_for_data (buf, buffer = cairo_image_surface_create_for_data (buf,
CAIRO_FORMAT_RGB24, CAIRO_FORMAT_RGB24,
priv->width, area->width,
priv->height, area->height,
priv->rowstride); area->rowstride);
cairo_surface_set_user_data (buffer, NULL, cairo_surface_set_user_data (buffer, NULL,
buf, (cairo_destroy_func_t) g_free); buf, (cairo_destroy_func_t) g_free);
} }
else else
{ {
buffer = cairo_image_surface_create_for_data (priv->buf, buffer = cairo_image_surface_create_for_data (area->buf,
CAIRO_FORMAT_RGB24, CAIRO_FORMAT_RGB24,
priv->width, area->width,
priv->height, area->height,
priv->rowstride); area->rowstride);
} }
cairo_set_source_surface (cr, buffer, 0.0, 0.0); cairo_set_source_surface (cr, buffer, 0.0, 0.0);
@ -459,28 +450,28 @@ gimp_color_area_draw (GtkWidget *widget,
cairo_paint (cr); cairo_paint (cr);
} }
if (priv->config && ! oog) if (area->config && ! oog)
oog = gimp_color_is_out_of_self_gamut (priv->color); oog = gimp_color_is_out_of_self_gamut (area->color);
if (priv->config && oog) if (area->config && oog)
{ {
GeglColor *oog_color; GeglColor *oog_color;
gint side = MIN (priv->width, priv->height) * 2 / 3; gint side = MIN (area->width, area->height) * 2 / 3;
cairo_move_to (cr, priv->width, 0); cairo_move_to (cr, area->width, 0);
cairo_line_to (cr, priv->width - side, 0); cairo_line_to (cr, area->width - side, 0);
cairo_line_to (cr, priv->width, side); cairo_line_to (cr, area->width, side);
cairo_line_to (cr, priv->width, 0); cairo_line_to (cr, area->width, 0);
oog_color = gimp_color_config_get_out_of_gamut_color (priv->config); oog_color = gimp_color_config_get_out_of_gamut_color (area->config);
gimp_cairo_set_source_color (cr, oog_color, priv->config, FALSE, widget); gimp_cairo_set_source_color (cr, oog_color, area->config, FALSE, widget);
cairo_fill (cr); cairo_fill (cr);
g_object_unref (oog_color); g_object_unref (oog_color);
} }
if (priv->draw_border) if (area->draw_border)
{ {
GdkRGBA color; GdkRGBA color;
@ -490,7 +481,7 @@ gimp_color_area_draw (GtkWidget *widget,
&color); &color);
gdk_cairo_set_source_rgba (cr, &color); gdk_cairo_set_source_rgba (cr, &color);
cairo_rectangle (cr, 0.5, 0.5, priv->width - 1, priv->height - 1); cairo_rectangle (cr, 0.5, 0.5, area->width - 1, area->height - 1);
cairo_stroke (cr); cairo_stroke (cr);
} }
@ -534,22 +525,18 @@ void
gimp_color_area_set_color (GimpColorArea *area, gimp_color_area_set_color (GimpColorArea *area,
GeglColor *color) GeglColor *color)
{ {
GimpColorAreaPrivate *priv;
g_return_if_fail (GIMP_IS_COLOR_AREA (area)); g_return_if_fail (GIMP_IS_COLOR_AREA (area));
g_return_if_fail (GEGL_IS_COLOR (color)); g_return_if_fail (GEGL_IS_COLOR (color));
priv = gimp_color_area_get_instance_private (area); if (! gimp_color_is_perceptually_identical (area->color, color))
if (! gimp_color_is_perceptually_identical (priv->color, color))
{ {
priv->needs_render = TRUE; area->needs_render = TRUE;
gtk_widget_queue_draw (GTK_WIDGET (area)); gtk_widget_queue_draw (GTK_WIDGET (area));
} }
color = gegl_color_duplicate (color); color = gegl_color_duplicate (color);
g_clear_object (&priv->color); g_clear_object (&area->color);
priv->color = color; area->color = color;
g_object_notify (G_OBJECT (area), "color"); g_object_notify (G_OBJECT (area), "color");
@ -568,13 +555,9 @@ gimp_color_area_set_color (GimpColorArea *area,
GeglColor * GeglColor *
gimp_color_area_get_color (GimpColorArea *area) gimp_color_area_get_color (GimpColorArea *area)
{ {
GimpColorAreaPrivate *priv;
g_return_val_if_fail (GIMP_IS_COLOR_AREA (area), NULL); g_return_val_if_fail (GIMP_IS_COLOR_AREA (area), NULL);
priv = gimp_color_area_get_instance_private (area); return gegl_color_duplicate (area->color);
return gegl_color_duplicate (priv->color);
} }
/** /**
@ -589,13 +572,9 @@ gimp_color_area_get_color (GimpColorArea *area)
gboolean gboolean
gimp_color_area_has_alpha (GimpColorArea *area) gimp_color_area_has_alpha (GimpColorArea *area)
{ {
GimpColorAreaPrivate *priv;
g_return_val_if_fail (GIMP_IS_COLOR_AREA (area), FALSE); g_return_val_if_fail (GIMP_IS_COLOR_AREA (area), FALSE);
priv = gimp_color_area_get_instance_private (area); return area->type != GIMP_COLOR_AREA_FLAT;
return priv->type != GIMP_COLOR_AREA_FLAT;
} }
/** /**
@ -611,17 +590,13 @@ void
gimp_color_area_set_type (GimpColorArea *area, gimp_color_area_set_type (GimpColorArea *area,
GimpColorAreaType type) GimpColorAreaType type)
{ {
GimpColorAreaPrivate *priv;
g_return_if_fail (GIMP_IS_COLOR_AREA (area)); g_return_if_fail (GIMP_IS_COLOR_AREA (area));
priv = gimp_color_area_get_instance_private (area); if (area->type != type)
if (priv->type != type)
{ {
priv->type = type; area->type = type;
priv->needs_render = TRUE; area->needs_render = TRUE;
gtk_widget_queue_draw (GTK_WIDGET (area)); gtk_widget_queue_draw (GTK_WIDGET (area));
g_object_notify (G_OBJECT (area), "type"); g_object_notify (G_OBJECT (area), "type");
@ -662,17 +637,13 @@ void
gimp_color_area_set_draw_border (GimpColorArea *area, gimp_color_area_set_draw_border (GimpColorArea *area,
gboolean draw_border) gboolean draw_border)
{ {
GimpColorAreaPrivate *priv;
g_return_if_fail (GIMP_IS_COLOR_AREA (area)); g_return_if_fail (GIMP_IS_COLOR_AREA (area));
priv = gimp_color_area_get_instance_private (area);
draw_border = draw_border ? TRUE : FALSE; draw_border = draw_border ? TRUE : FALSE;
if (priv->draw_border != draw_border) if (area->draw_border != draw_border)
{ {
priv->draw_border = draw_border; area->draw_border = draw_border;
gtk_widget_queue_draw (GTK_WIDGET (area)); gtk_widget_queue_draw (GTK_WIDGET (area));
@ -700,14 +671,11 @@ void
gimp_color_area_set_out_of_gamut (GimpColorArea *area, gimp_color_area_set_out_of_gamut (GimpColorArea *area,
gboolean out_of_gamut) gboolean out_of_gamut)
{ {
GimpColorAreaPrivate *priv;
g_return_if_fail (GIMP_IS_COLOR_AREA (area)); g_return_if_fail (GIMP_IS_COLOR_AREA (area));
priv = gimp_color_area_get_instance_private (area); if (area->out_of_gamut != out_of_gamut)
if (priv->out_of_gamut != out_of_gamut)
{ {
priv->out_of_gamut = out_of_gamut; area->out_of_gamut = out_of_gamut;
gtk_widget_queue_draw (GTK_WIDGET (area)); gtk_widget_queue_draw (GTK_WIDGET (area));
} }
} }
@ -725,29 +693,25 @@ void
gimp_color_area_set_color_config (GimpColorArea *area, gimp_color_area_set_color_config (GimpColorArea *area,
GimpColorConfig *config) GimpColorConfig *config)
{ {
GimpColorAreaPrivate *priv;
g_return_if_fail (GIMP_IS_COLOR_AREA (area)); g_return_if_fail (GIMP_IS_COLOR_AREA (area));
g_return_if_fail (config == NULL || GIMP_IS_COLOR_CONFIG (config)); g_return_if_fail (config == NULL || GIMP_IS_COLOR_CONFIG (config));
priv = gimp_color_area_get_instance_private (area); if (config != area->config)
if (config != priv->config)
{ {
if (priv->config) if (area->config)
{ {
g_signal_handlers_disconnect_by_func (priv->config, g_signal_handlers_disconnect_by_func (area->config,
gimp_color_area_destroy_transform, gimp_color_area_destroy_transform,
area); area);
gimp_color_area_destroy_transform (area); gimp_color_area_destroy_transform (area);
} }
g_set_object (&priv->config, config); g_set_object (&area->config, config);
if (priv->config) if (area->config)
{ {
g_signal_connect_swapped (priv->config, "notify", g_signal_connect_swapped (area->config, "notify",
G_CALLBACK (gimp_color_area_destroy_transform), G_CALLBACK (gimp_color_area_destroy_transform),
area); area);
} }
@ -767,7 +731,6 @@ gimp_color_area_render_buf (GtkWidget *widget,
GeglColor *color) GeglColor *color)
{ {
GimpColorArea *area = GIMP_COLOR_AREA (widget); GimpColorArea *area = GIMP_COLOR_AREA (widget);
GimpColorAreaPrivate *priv = gimp_color_area_get_instance_private (area);
const Babl *render_space; const Babl *render_space;
guint x, y; guint x, y;
guint check_size = 0; guint check_size = 0;
@ -793,7 +756,7 @@ gimp_color_area_render_buf (GtkWidget *widget,
break; break;
} }
render_space = gimp_widget_get_render_space (widget, priv->config); render_space = gimp_widget_get_render_space (widget, area->config);
gegl_color_get_pixel (color, babl_format_with_space ("R'G'B'A u8", render_space), opaque); gegl_color_get_pixel (color, babl_format_with_space ("R'G'B'A u8", render_space), opaque);
gegl_color_get_pixel (color, babl_format_with_space ("R'G'B'A double", render_space), opaque_d); gegl_color_get_pixel (color, babl_format_with_space ("R'G'B'A double", render_space), opaque_d);
@ -902,18 +865,16 @@ gimp_color_area_render_buf (GtkWidget *widget,
static void static void
gimp_color_area_render (GimpColorArea *area) gimp_color_area_render (GimpColorArea *area)
{ {
GimpColorAreaPrivate *priv = gimp_color_area_get_instance_private (area); if (! area->buf)
if (! priv->buf)
return; return;
gimp_color_area_render_buf (GTK_WIDGET (area), gimp_color_area_render_buf (GTK_WIDGET (area),
priv->type, area->type,
priv->buf, area->buf,
priv->width, priv->height, priv->rowstride, area->width, area->height, area->rowstride,
priv->color); area->color);
priv->needs_render = FALSE; area->needs_render = FALSE;
} }
static void static void
@ -921,7 +882,6 @@ gimp_color_area_drag_begin (GtkWidget *widget,
GdkDragContext *context) GdkDragContext *context)
{ {
GimpColorArea *area = GIMP_COLOR_AREA (widget); GimpColorArea *area = GIMP_COLOR_AREA (widget);
GimpColorAreaPrivate *priv = gimp_color_area_get_instance_private (area);
GeglColor *color; GeglColor *color;
GtkWidget *window; GtkWidget *window;
GtkWidget *frame; GtkWidget *frame;
@ -938,7 +898,7 @@ gimp_color_area_drag_begin (GtkWidget *widget,
gtk_container_add (GTK_CONTAINER (window), frame); gtk_container_add (GTK_CONTAINER (window), frame);
color = gimp_color_area_get_color (GIMP_COLOR_AREA (widget)); color = gimp_color_area_get_color (GIMP_COLOR_AREA (widget));
color_area = gimp_color_area_new (color, priv->type, 0); color_area = gimp_color_area_new (color, area->type, 0);
g_object_unref (color); g_object_unref (color);
gtk_widget_set_size_request (color_area, gtk_widget_set_size_request (color_area,
@ -1066,7 +1026,6 @@ gimp_color_area_drag_data_get (GtkWidget *widget,
guint time) guint time)
{ {
GimpColorArea *area = GIMP_COLOR_AREA (widget); GimpColorArea *area = GIMP_COLOR_AREA (widget);
GimpColorAreaPrivate *priv = gimp_color_area_get_instance_private (area);
const Babl *format; const Babl *format;
const gchar *encoding; const gchar *encoding;
gint encoding_length; gint encoding_length;
@ -1078,13 +1037,13 @@ gimp_color_area_drag_data_get (GtkWidget *widget,
gint data_length; gint data_length;
g_return_if_fail (selection_data != NULL); g_return_if_fail (selection_data != NULL);
g_return_if_fail (priv->color != NULL); g_return_if_fail (area->color != NULL);
format = gegl_color_get_format (priv->color); format = gegl_color_get_format (area->color);
encoding = babl_format_get_encoding (format); encoding = babl_format_get_encoding (format);
encoding_length = strlen (encoding) + 1; encoding_length = strlen (encoding) + 1;
pixel_length = babl_format_get_bytes_per_pixel (format); pixel_length = babl_format_get_bytes_per_pixel (format);
gegl_color_get_pixel (priv->color, format, pixel); gegl_color_get_pixel (area->color, format, pixel);
if (babl_format_get_space (format) != babl_space ("sRGB")) if (babl_format_get_space (format) != babl_space ("sRGB"))
profile_data = (guint8 *) babl_space_get_icc (babl_format_get_space (format), profile_data = (guint8 *) babl_space_get_icc (babl_format_get_space (format),
@ -1105,9 +1064,7 @@ gimp_color_area_drag_data_get (GtkWidget *widget,
static void static void
gimp_color_area_create_transform (GimpColorArea *area) gimp_color_area_create_transform (GimpColorArea *area)
{ {
GimpColorAreaPrivate *priv = gimp_color_area_get_instance_private (area); if (area->config)
if (priv->config)
{ {
static GimpColorProfile *profile = NULL; static GimpColorProfile *profile = NULL;
@ -1116,8 +1073,8 @@ gimp_color_area_create_transform (GimpColorArea *area)
if (G_UNLIKELY (! profile)) if (G_UNLIKELY (! profile))
profile = gimp_color_profile_new_rgb_srgb (); profile = gimp_color_profile_new_rgb_srgb ();
priv->transform = gimp_widget_get_color_transform (GTK_WIDGET (area), area->transform = gimp_widget_get_color_transform (GTK_WIDGET (area),
priv->config, area->config,
profile, profile,
format, format,
format, format,
@ -1130,9 +1087,7 @@ gimp_color_area_create_transform (GimpColorArea *area)
static void static void
gimp_color_area_destroy_transform (GimpColorArea *area) gimp_color_area_destroy_transform (GimpColorArea *area)
{ {
GimpColorAreaPrivate *priv = gimp_color_area_get_instance_private (area); g_clear_object (&area->transform);
g_clear_object (&priv->transform);
gtk_widget_queue_draw (GTK_WIDGET (area)); gtk_widget_queue_draw (GTK_WIDGET (area));
} }

View file

@ -35,24 +35,7 @@ G_BEGIN_DECLS
#define GIMP_TYPE_COLOR_AREA (gimp_color_area_get_type ()) #define GIMP_TYPE_COLOR_AREA (gimp_color_area_get_type ())
G_DECLARE_DERIVABLE_TYPE (GimpColorArea, gimp_color_area, GIMP, COLOR_AREA, GtkDrawingArea) G_DECLARE_FINAL_TYPE (GimpColorArea, gimp_color_area, GIMP, COLOR_AREA, GtkDrawingArea)
struct _GimpColorAreaClass
{
GtkDrawingAreaClass parent_class;
void (* color_changed) (GimpColorArea *area);
/* Padding for future expansion */
void (* _gimp_reserved1) (void);
void (* _gimp_reserved2) (void);
void (* _gimp_reserved3) (void);
void (* _gimp_reserved4) (void);
void (* _gimp_reserved5) (void);
void (* _gimp_reserved6) (void);
void (* _gimp_reserved7) (void);
void (* _gimp_reserved8) (void);
};
GtkWidget * gimp_color_area_new (GeglColor *color, GtkWidget * gimp_color_area_new (GeglColor *color,