diff --git a/gtk/gtkcolorscale.c b/gtk/gtkcolorscale.c index a606e048a9..40cc3e05d3 100644 --- a/gtk/gtkcolorscale.c +++ b/gtk/gtkcolorscale.c @@ -36,6 +36,7 @@ typedef struct { GdkRGBA color; GtkColorScaleType type; + GdkTexture *hue_texture; } GtkColorScalePrivate; enum @@ -63,45 +64,59 @@ gtk_color_scale_snapshot_trough (GtkColorScale *scale, if (width <= 1 || height <= 1) return; + if (priv->hue_texture && + (width != gdk_texture_get_width (priv->hue_texture) || + height != gdk_texture_get_height (priv->hue_texture))) + g_clear_object (&priv->hue_texture); + if (priv->type == GTK_COLOR_SCALE_HUE) { - GdkTexture *texture; - gint stride; - GBytes *bytes; - guchar *data, *p; - gdouble h; - gdouble r, g, b; - gdouble f; - int hue_x, hue_y; - - stride = width * 3; - data = g_malloc (width * height * 3); - - f = 1.0 / (height - 1); - for (hue_y = 0; hue_y < height; hue_y++) + if (!priv->hue_texture) { - h = CLAMP (hue_y * f, 0.0, 1.0); - p = data + hue_y * stride; - for (hue_x = 0; hue_x < stride; hue_x += 3) + GdkTexture *texture; + gint stride; + GBytes *bytes; + guchar *data, *p; + gdouble h; + gdouble r, g, b; + gdouble f; + int hue_x, hue_y; + + stride = width * 3; + data = g_malloc (width * height * 3); + + f = 1.0 / (height - 1); + for (hue_y = 0; hue_y < height; hue_y++) { - gtk_hsv_to_rgb (h, 1, 1, &r, &g, &b); - p[hue_x + 0] = CLAMP (r * 255, 0, 255); - p[hue_x + 1] = CLAMP (g * 255, 0, 255); - p[hue_x + 2] = CLAMP (b * 255, 0, 255); + h = CLAMP (hue_y * f, 0.0, 1.0); + p = data + hue_y * stride; + for (hue_x = 0; hue_x < stride; hue_x += 3) + { + gtk_hsv_to_rgb (h, 1, 1, &r, &g, &b); + p[hue_x + 0] = CLAMP (r * 255, 0, 255); + p[hue_x + 1] = CLAMP (g * 255, 0, 255); + p[hue_x + 2] = CLAMP (b * 255, 0, 255); + } } + + bytes = g_bytes_new_take (data, width * height * 3); + texture = gdk_memory_texture_new (width, height, + GDK_MEMORY_R8G8B8, + bytes, + stride); + g_bytes_unref (bytes); + + gtk_snapshot_append_texture (snapshot, + texture, + &GRAPHENE_RECT_INIT(0, 0, width, height)); + priv->hue_texture = texture; + } + else + { + gtk_snapshot_append_texture (snapshot, + priv->hue_texture, + &GRAPHENE_RECT_INIT(0, 0, width, height)); } - - bytes = g_bytes_new_take (data, width * height * 3); - texture = gdk_memory_texture_new (width, height, - GDK_MEMORY_R8G8B8, - bytes, - stride); - g_bytes_unref (bytes); - - gtk_snapshot_append_texture (snapshot, - texture, - &GRAPHENE_RECT_INIT(0, 0, width, height)); - g_object_unref (texture); } else if (priv->type == GTK_COLOR_SCALE_ALPHA) { @@ -242,11 +257,22 @@ hold_action (GtkGestureLongPress *gesture, g_signal_emit_by_name (scale, "popup-menu", &handled); } +static void +scale_finalize (GObject *object) +{ + GtkColorScalePrivate *priv = gtk_color_scale_get_instance_private (GTK_COLOR_SCALE (object)); + + g_clear_object (&priv->hue_texture); + + G_OBJECT_CLASS (gtk_color_scale_parent_class)->finalize (object); +} + static void gtk_color_scale_class_init (GtkColorScaleClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); + object_class->finalize = scale_finalize; object_class->get_property = scale_get_property; object_class->set_property = scale_set_property;