From 8eb56586aa28e77964009ee618e67df10e7b912e Mon Sep 17 00:00:00 2001 From: Jehan Date: Thu, 23 Nov 2023 22:08:09 +0100 Subject: [PATCH] app, libgimpwidgets, plug-ins: GimpColorArea is now space-invaded. This includes improvements on the out-of-gamut colored corner being shown for unbounded component types out of the [0; 1] range (with some small margin of error to avoid e.g. a -0.0000001 value to show as out-of-gamut). There are still improvements to be made on the color rendering. In particular, it still draws as CAIRO_FORMAT_RGB24 cairo surface. We should probably move to draw as CAIRO_FORMAT_RGBA128F eventually (more precision and even allowing to draw unbounded colors with a possible option, instead of always clipping). Also adding the libgimpwidgets API gimp_widget_get_render_space(). --- app/dialogs/item-options-dialog.c | 12 +- app/propgui/gimppropgui-hue-saturation.c | 18 +- app/tools/gimpcolorpickertool.c | 12 +- app/widgets/gimpaction.c | 12 +- app/widgets/gimpcolorframe.c | 19 +- app/widgets/gimpcolorhistory.c | 32 ++-- app/widgets/gimpdashboard.c | 8 +- app/widgets/gimpdnd.c | 13 +- app/widgets/gimpgradienteditor.c | 19 +- app/widgets/gimpmenu.c | 14 +- libgimpwidgets/gimpcairo-utils.c | 16 +- libgimpwidgets/gimpcolorarea.c | 211 ++++++++++++++++------- libgimpwidgets/gimpcolorarea.h | 7 +- libgimpwidgets/gimpcolorbutton.c | 27 ++- libgimpwidgets/gimpcolorselection.c | 53 ++++-- libgimpwidgets/gimplabelcolor.c | 19 +- libgimpwidgets/gimppropwidgets.c | 21 +-- libgimpwidgets/gimpwidgets.def | 1 + libgimpwidgets/gimpwidgetsutils.c | 41 +++++ libgimpwidgets/gimpwidgetsutils.h | 14 +- plug-ins/ifs-compose/ifs-compose.c | 18 +- 21 files changed, 392 insertions(+), 195 deletions(-) diff --git a/app/dialogs/item-options-dialog.c b/app/dialogs/item-options-dialog.c index 04808b6d74..31f5acbe9e 100644 --- a/app/dialogs/item-options-dialog.c +++ b/app/dialogs/item-options-dialog.c @@ -216,7 +216,7 @@ item_options_dialog_new (GimpImage *image, list = g_list_next (list)) { GimpColorTag color_tag; - GimpRGB color; + GimpRGB rgb; GtkWidget *image; radio = list->data; @@ -228,15 +228,19 @@ item_options_dialog_new (GimpImage *image, color_tag = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (radio), "gimp-item-data")); - if (gimp_get_color_tag_color (color_tag, &color, FALSE)) + if (gimp_get_color_tag_color (color_tag, &rgb, FALSE)) { - gint w, h; + GeglColor *color = gegl_color_new (NULL); + gint w, h; - image = gimp_color_area_new (&color, GIMP_COLOR_AREA_FLAT, 0); + gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &rgb); + image = gimp_color_area_new (color, GIMP_COLOR_AREA_FLAT, 0); gimp_color_area_set_color_config (GIMP_COLOR_AREA (image), context->gimp->config->color_management); gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h); gtk_widget_set_size_request (image, w, h); + + g_object_unref (color); } else { diff --git a/app/propgui/gimppropgui-hue-saturation.c b/app/propgui/gimppropgui-hue-saturation.c index 7104e5bbf3..2d1f96948b 100644 --- a/app/propgui/gimppropgui-hue-saturation.c +++ b/app/propgui/gimppropgui-hue-saturation.c @@ -50,7 +50,8 @@ hue_saturation_config_notify (GObject *object, { GimpHueSaturationConfig *config = GIMP_HUE_SATURATION_CONFIG (object); GimpHueRange range; - GimpRGB color; + GeglColor *color; + GimpRGB rgb; static const GimpRGB default_colors[7] = { @@ -65,11 +66,14 @@ hue_saturation_config_notify (GObject *object, range = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (color_area), "hue-range")); - color = default_colors[range]; + rgb = default_colors[range]; - gimp_operation_hue_saturation_map (config, &color, range, &color); + gimp_operation_hue_saturation_map (config, &rgb, range, &rgb); - gimp_color_area_set_color (GIMP_COLOR_AREA (color_area), &color); + color = gegl_color_new (NULL); + gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &rgb); + gimp_color_area_set_color (GIMP_COLOR_AREA (color_area), color); + g_object_unref (color); } static void @@ -189,7 +193,7 @@ _gimp_prop_gui_new_hue_saturation (GObject *config, if (i > 0) { GtkWidget *color_area; - GimpRGB color = { 0, }; + GeglColor *color = gegl_color_new ("transparent"); frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); @@ -199,7 +203,7 @@ _gimp_prop_gui_new_hue_saturation (GObject *config, 1, 1); gtk_widget_show (frame); - color_area = gimp_color_area_new (&color, GIMP_COLOR_AREA_FLAT, 0); + color_area = gimp_color_area_new (color, GIMP_COLOR_AREA_FLAT, 0); gtk_widget_set_size_request (color_area, COLOR_WIDTH, COLOR_HEIGHT); gtk_container_add (GTK_CONTAINER (frame), color_area); gtk_widget_show (color_area); @@ -210,6 +214,8 @@ _gimp_prop_gui_new_hue_saturation (GObject *config, G_CALLBACK (hue_saturation_config_notify), color_area, 0); hue_saturation_config_notify (config, NULL, color_area); + + g_object_unref (color); } g_signal_connect (button, "toggled", diff --git a/app/tools/gimpcolorpickertool.c b/app/tools/gimpcolorpickertool.c index b90ad55505..ccdd5dc578 100644 --- a/app/tools/gimpcolorpickertool.c +++ b/app/tools/gimpcolorpickertool.c @@ -339,7 +339,7 @@ gimp_color_picker_tool_info_create (GimpColorPickerTool *picker_tool, GList *drawables = gimp_image_get_selected_drawables (image); GtkWidget *hbox; GtkWidget *frame; - GimpRGB color; + GeglColor *color; picker_tool->gui = gimp_tool_gui_new (tool->tool_info, NULL, @@ -395,9 +395,9 @@ gimp_color_picker_tool_info_create (GimpColorPickerTool *picker_tool, gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); gtk_widget_show (frame); - gimp_rgba_set (&color, 0.0, 0.0, 0.0, 0.0); + color = gegl_color_new ("transparent"); picker_tool->color_area = - gimp_color_area_new (&color, + gimp_color_area_new (color, drawables && gimp_drawable_has_alpha (drawables->data) ? GIMP_COLOR_AREA_LARGE_CHECKS : GIMP_COLOR_AREA_FLAT, @@ -410,6 +410,7 @@ gimp_color_picker_tool_info_create (GimpColorPickerTool *picker_tool, gtk_widget_show (picker_tool->color_area); g_list_free (drawables); + g_object_unref (color); } static void @@ -435,7 +436,6 @@ gimp_color_picker_tool_info_update (GimpColorPickerTool *picker_tool, GimpTool *tool = GIMP_TOOL (picker_tool); GimpImage *image = gimp_display_get_image (display); GList *drawables = gimp_image_get_selected_drawables (image); - GimpRGB rgb; tool->display = display; @@ -444,9 +444,7 @@ gimp_color_picker_tool_info_update (GimpColorPickerTool *picker_tool, gimp_tool_gui_set_viewables (picker_tool->gui, drawables); g_list_free (drawables); - gegl_color_get_rgba_with_space (color, &rgb.r, &rgb.g, &rgb.b, &rgb.a, NULL); - gimp_color_area_set_color (GIMP_COLOR_AREA (picker_tool->color_area), &rgb); - + gimp_color_area_set_color (GIMP_COLOR_AREA (picker_tool->color_area), color); gimp_color_frame_set_color (GIMP_COLOR_FRAME (picker_tool->color_frame1), sample_average, color, x, y); gimp_color_frame_set_color (GIMP_COLOR_FRAME (picker_tool->color_frame2), diff --git a/app/widgets/gimpaction.c b/app/widgets/gimpaction.c index 5c629114af..ffa6eda2da 100644 --- a/app/widgets/gimpaction.c +++ b/app/widgets/gimpaction.c @@ -1009,22 +1009,26 @@ gimp_action_set_proxy (GimpAction *action, { if (priv->color) { + GeglColor *color; + if (GTK_IS_MENU_ITEM (proxy)) proxy_image = gimp_menu_item_get_image (GTK_MENU_ITEM (proxy)); else proxy_image = gtk_tool_button_get_label_widget (GTK_TOOL_BUTTON (proxy)); + color = gegl_color_new (NULL); + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), priv->color); + if (GIMP_IS_COLOR_AREA (proxy_image)) { - gimp_color_area_set_color (GIMP_COLOR_AREA (proxy_image), priv->color); + gimp_color_area_set_color (GIMP_COLOR_AREA (proxy_image), color); proxy_image = NULL; } else { gint width, height; - proxy_image = gimp_color_area_new (priv->color, - GIMP_COLOR_AREA_SMALL_CHECKS, 0); + proxy_image = gimp_color_area_new (color, GIMP_COLOR_AREA_SMALL_CHECKS, 0); gimp_color_area_set_draw_border (GIMP_COLOR_AREA (proxy_image), TRUE); if (priv->context) @@ -1035,6 +1039,8 @@ gimp_action_set_proxy (GimpAction *action, gtk_widget_set_size_request (proxy_image, width, height); gtk_widget_show (proxy_image); } + + g_object_unref (color); } else if (priv->viewable) { diff --git a/app/widgets/gimpcolorframe.c b/app/widgets/gimpcolorframe.c index 1e55a97eff..f2a04a2b2b 100644 --- a/app/widgets/gimpcolorframe.c +++ b/app/widgets/gimpcolorframe.c @@ -190,7 +190,7 @@ gimp_color_frame_init (GimpColorFrame *frame) frame->color_area = g_object_new (GIMP_TYPE_COLOR_AREA, - "color", &frame->color, + "color", frame->color, "type", GIMP_COLOR_AREA_SMALL_CHECKS, "drag-mask", GDK_BUTTON1_MASK, "draw-border", TRUE, @@ -755,11 +755,9 @@ gimp_color_frame_update (GimpColorFrame *frame) if (frame->sample_valid) { - GimpRGB rgb; - gchar str[16]; + gchar str[16]; - gegl_color_get_pixel (frame->color, babl_format ("R'G'B'A double"), &rgb); - gimp_color_area_set_color (GIMP_COLOR_AREA (frame->color_area), &rgb); + gimp_color_area_set_color (GIMP_COLOR_AREA (frame->color_area), frame->color); g_snprintf (str, sizeof (str), "%d", frame->x); gtk_label_set_text (GTK_LABEL (frame->coords_label_x), str); @@ -960,7 +958,7 @@ gimp_color_frame_update (GimpColorFrame *frame) { const Babl *print_format; gfloat grayscale[2]; - GimpRGB grayscale_color; + GeglColor *grayscale_color; print_format = gimp_babl_format (GIMP_GRAY, gimp_babl_precision (GIMP_COMPONENT_TYPE_FLOAT, trc), @@ -969,10 +967,11 @@ gimp_color_frame_update (GimpColorFrame *frame) /* Change color area color to grayscale if image is not * in Grayscale Mode */ - gimp_rgba_set (&grayscale_color, grayscale[0], grayscale[0], - grayscale[0], GIMP_OPACITY_OPAQUE); - gimp_color_area_set_color (GIMP_COLOR_AREA (frame->color_area), - &grayscale_color); + grayscale_color = gegl_color_duplicate (frame->color); + gegl_color_set_pixel (grayscale_color, print_format, grayscale); + gimp_color_set_alpha (grayscale_color, GIMP_OPACITY_OPAQUE); + gimp_color_area_set_color (GIMP_COLOR_AREA (frame->color_area), grayscale_color); + g_object_unref (grayscale_color); values = g_new0 (gchar *, 5); diff --git a/app/widgets/gimpcolorhistory.c b/app/widgets/gimpcolorhistory.c index 643ce8f9eb..6166224f67 100644 --- a/app/widgets/gimpcolorhistory.c +++ b/app/widgets/gimpcolorhistory.c @@ -263,8 +263,8 @@ gimp_color_history_set_property (GObject *object, for (i = 0; i < history->history_size; i++) { - GimpRGB black = { 0.0, 0.0, 0.0, 1.0 }; - gint row, column; + GeglColor *black = gegl_color_new ("black"); + gint row, column; column = i % (history->history_size / history->n_rows); row = i / (history->history_size / history->n_rows); @@ -274,7 +274,7 @@ gimp_color_history_set_property (GObject *object, gtk_grid_attach (GTK_GRID (history), button, column, row, 1, 1); gtk_widget_show (button); - color_area = gimp_color_area_new (&black, GIMP_COLOR_AREA_SMALL_CHECKS, + color_area = gimp_color_area_new (black, GIMP_COLOR_AREA_SMALL_CHECKS, GDK_BUTTON2_MASK); gimp_color_area_set_color_config (GIMP_COLOR_AREA (color_area), history->context->gimp->config->color_management); @@ -291,6 +291,8 @@ gimp_color_history_set_property (GObject *object, history->buttons[i] = button; history->color_areas[i] = color_area; + + g_object_unref (black); } gimp_color_history_palette_dirty (history); @@ -456,14 +458,16 @@ gimp_color_history_color_clicked (GtkWidget *widget, GimpColorHistory *history) { GimpColorArea *color_area; - GimpRGB color; + GeglColor *color; + GimpRGB rgb; color_area = GIMP_COLOR_AREA (gtk_bin_get_child (GTK_BIN (widget))); - gimp_color_area_get_color (color_area, &color); + color = gimp_color_area_get_color (color_area); + gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &rgb); + g_object_unref (color); - g_signal_emit (history, history_signals[COLOR_SELECTED], 0, - &color); + g_signal_emit (history, history_signals[COLOR_SELECTED], 0, &rgb); } /* Color history palette callback. */ @@ -496,10 +500,9 @@ gimp_color_history_palette_dirty (GimpColorHistory *history) gimp_color_history_color_changed, GINT_TO_POINTER (i)); - gimp_color_area_set_color (GIMP_COLOR_AREA (history->color_areas[i]), - &rgb); - gegl_color_set_rgba_with_space (color, rgb.r, rgb.g, rgb.b, rgb.a, NULL); + gimp_color_area_set_color (GIMP_COLOR_AREA (history->color_areas[i]), color); + if (/* Common out-of-gamut case */ (rgb.r < 0.0 || rgb.r > 1.0 || rgb.g < 0.0 || rgb.g > 1.0 || @@ -530,16 +533,19 @@ gimp_color_history_color_changed (GtkWidget *widget, { GimpColorHistory *history; GimpPalette *palette; - GimpRGB color; + GeglColor *color; + GimpRGB rgb; history = GIMP_COLOR_HISTORY (gtk_widget_get_ancestor (widget, GIMP_TYPE_COLOR_HISTORY)); palette = gimp_palettes_get_color_history (history->context->gimp); - gimp_color_area_get_color (GIMP_COLOR_AREA (widget), &color); + color = gimp_color_area_get_color (GIMP_COLOR_AREA (widget)); + gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &rgb); + g_object_unref (color); - gimp_palette_set_entry_color (palette, GPOINTER_TO_INT (data), &color, FALSE); + gimp_palette_set_entry_color (palette, GPOINTER_TO_INT (data), &rgb, FALSE); } static void diff --git a/app/widgets/gimpdashboard.c b/app/widgets/gimpdashboard.c index b0a9f94d95..4e597f0084 100644 --- a/app/widgets/gimpdashboard.c +++ b/app/widgets/gimpdashboard.c @@ -2905,8 +2905,10 @@ gimp_dashboard_update_group (GimpDashboard *dashboard, if (group_info->has_meter && field_info->meter_value) { - color_area = gimp_color_area_new (&variable_info->color, - GIMP_COLOR_AREA_FLAT, 0); + GeglColor *color = gegl_color_new (NULL); + + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), &variable_info->color); + color_area = gimp_color_area_new (color, GIMP_COLOR_AREA_FLAT, 0); gimp_help_set_help_data (color_area, description, NULL); gtk_widget_set_size_request (color_area, 5, 5); @@ -2914,6 +2916,8 @@ gimp_dashboard_update_group (GimpDashboard *dashboard, gtk_grid_attach (group_data->grid, color_area, 0, n_rows, 1, 1); gtk_widget_show (color_area); + + g_object_unref (color); } str = g_strdup_printf ("%s:", diff --git a/app/widgets/gimpdnd.c b/app/widgets/gimpdnd.c index 9e6c1fc5b4..7b769096f1 100644 --- a/app/widgets/gimpdnd.c +++ b/app/widgets/gimpdnd.c @@ -1387,22 +1387,27 @@ gimp_dnd_get_color_icon (GtkWidget *widget, gpointer get_color_data) { GtkWidget *color_area; - GimpRGB color; + GeglColor *color; + GimpRGB rgb; - (* (GimpDndDragColorFunc) get_color_func) (widget, &color, get_color_data); + (* (GimpDndDragColorFunc) get_color_func) (widget, &rgb, get_color_data); GIMP_LOG (DND, "called"); g_object_set_data_full (G_OBJECT (context), - "gimp-dnd-color", g_memdup2 (&color, sizeof (GimpRGB)), + "gimp-dnd-color", g_memdup2 (&rgb, sizeof (GimpRGB)), (GDestroyNotify) g_free); - color_area = gimp_color_area_new (&color, GIMP_COLOR_AREA_SMALL_CHECKS, 0); + color = gegl_color_new (NULL); + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), &rgb); + color_area = gimp_color_area_new (color, GIMP_COLOR_AREA_SMALL_CHECKS, 0); gimp_color_area_set_color_config (GIMP_COLOR_AREA (color_area), the_dnd_gimp->config->color_management); gtk_widget_set_size_request (color_area, DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE); + g_object_unref (color); + return color_area; } diff --git a/app/widgets/gimpgradienteditor.c b/app/widgets/gimpgradienteditor.c index 6c42b8a60d..7739d4e6f2 100644 --- a/app/widgets/gimpgradienteditor.c +++ b/app/widgets/gimpgradienteditor.c @@ -314,9 +314,9 @@ gimp_gradient_editor_init (GimpGradientEditor *editor) GtkWidget *vbox; GtkWidget *hbox; GtkWidget *hint_vbox; - GimpRGB transp; + GeglColor *transp; - gimp_rgba_set (&transp, 0.0, 0.0, 0.0, 0.0); + transp = gegl_color_new ("transparent"); /* Frame for gradient view and gradient control */ frame = gtk_frame_new (NULL); @@ -415,7 +415,7 @@ gimp_gradient_editor_init (GimpGradientEditor *editor) gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0); gtk_widget_show (frame); - editor->current_color = gimp_color_area_new (&transp, + editor->current_color = gimp_color_area_new (transp, GIMP_COLOR_AREA_SMALL_CHECKS, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK); @@ -447,6 +447,8 @@ gimp_gradient_editor_init (GimpGradientEditor *editor) gimp_rgba_set (&editor->saved_colors[7], 0.0, 1.0, 1.0, GIMP_OPACITY_OPAQUE); gimp_rgba_set (&editor->saved_colors[8], 0.0, 0.0, 1.0, GIMP_OPACITY_OPAQUE); gimp_rgba_set (&editor->saved_colors[9], 1.0, 0.0, 1.0, GIMP_OPACITY_OPAQUE); + + g_object_unref (transp); } static void @@ -1283,6 +1285,7 @@ view_set_hint (GimpGradientEditor *editor, gint x) { GimpDataEditor *data_editor = GIMP_DATA_EDITOR (editor); + GeglColor *color = gegl_color_new ("black"); GimpRGB rgb; GimpHSV hsv; gdouble xpos; @@ -1297,7 +1300,8 @@ view_set_hint (GimpGradientEditor *editor, data_editor->context, NULL, xpos, FALSE, FALSE, &rgb); - gimp_color_area_set_color (GIMP_COLOR_AREA (editor->current_color), &rgb); + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), &rgb); + gimp_color_area_set_color (GIMP_COLOR_AREA (editor->current_color), color); gimp_rgb_to_hsv (&rgb, &hsv); @@ -1312,6 +1316,7 @@ view_set_hint (GimpGradientEditor *editor, gradient_editor_set_hint (editor, str1, str2, str3, str4); + g_object_unref (color); g_free (str1); g_free (str2); g_free (str3); @@ -1325,11 +1330,11 @@ view_pick_color (GimpGradientEditor *editor, gint x) { GimpDataEditor *data_editor = GIMP_DATA_EDITOR (editor); + GeglColor *color = gegl_color_new ("black"); GimpRGB rgb; gdouble xpos; gchar *str2; gchar *str3; - GeglColor *color = gegl_color_new ("black"); xpos = control_calc_g_pos (editor, x); @@ -1337,7 +1342,8 @@ view_pick_color (GimpGradientEditor *editor, data_editor->context, NULL, xpos, FALSE, FALSE, &rgb); - gimp_color_area_set_color (GIMP_COLOR_AREA (editor->current_color), &rgb); + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), &rgb); + gimp_color_area_set_color (GIMP_COLOR_AREA (editor->current_color), color); str2 = g_strdup_printf (_("RGB (%d, %d, %d)"), (gint) (rgb.r * 255.0), @@ -1346,7 +1352,6 @@ view_pick_color (GimpGradientEditor *editor, str3 = g_strdup_printf ("(%0.3f, %0.3f, %0.3f)", rgb.r, rgb.g, rgb.b); - gegl_color_set_rgba_with_space (color, rgb.r, rgb.g, rgb.b, rgb.a, NULL); if (pick_target == GIMP_COLOR_PICK_TARGET_FOREGROUND) { gimp_context_set_foreground (data_editor->context, color); diff --git a/app/widgets/gimpmenu.c b/app/widgets/gimpmenu.c index bb628cee3e..31f198044e 100644 --- a/app/widgets/gimpmenu.c +++ b/app/widgets/gimpmenu.c @@ -671,16 +671,20 @@ gimp_menu_submenu_notify_color (GimpMenuModel *model, const GParamSpec *pspec, GtkMenuItem *item) { - GimpRGB *color = NULL; + GimpRGB *rgb = NULL; GtkWidget *image = NULL; gint width, height; g_object_get (model, - "color", &color, + "color", &rgb, NULL); - if (color) + if (rgb) { + GeglColor *color; + + color = gegl_color_new (NULL); + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), rgb); image = gimp_color_area_new (color, GIMP_COLOR_AREA_SMALL_CHECKS, 0); gimp_color_area_set_draw_border (GIMP_COLOR_AREA (image), TRUE); @@ -691,10 +695,12 @@ gimp_menu_submenu_notify_color (GimpMenuModel *model, gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height); gtk_widget_set_size_request (image, width, height); gtk_widget_show (image); + + g_object_unref (color); } gimp_menu_item_set_image (item, image, NULL); - g_free (color); + g_free (rgb); } static void diff --git a/libgimpwidgets/gimpcairo-utils.c b/libgimpwidgets/gimpcairo-utils.c index ed5cab4d9a..c36b150838 100644 --- a/libgimpwidgets/gimpcairo-utils.c +++ b/libgimpwidgets/gimpcairo-utils.c @@ -234,23 +234,13 @@ gimp_cairo_set_source_color (cairo_t *cr, gboolean softproof, GtkWidget *widget) { - GimpColorProfile *proof_profile = NULL; - GimpColorProfile *dest_profile = NULL; - const Babl *space = NULL; - gdouble rgba[4]; + const Babl *space; + gdouble rgba[4]; g_return_if_fail (GEGL_IS_COLOR (color)); g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget)); - _gimp_widget_get_profiles (widget, config, - softproof ? &proof_profile : NULL, - &dest_profile); - - if (dest_profile) - space = gimp_color_profile_get_space (dest_profile, - GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC, - NULL); + space = gimp_widget_get_render_space (widget, config); gegl_color_get_pixel (color, babl_format_with_space ("R'G'B'A double", space), rgba); - cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]); } diff --git a/libgimpwidgets/gimpcolorarea.c b/libgimpwidgets/gimpcolorarea.c index c84a9a0522..98eee9cf67 100644 --- a/libgimpwidgets/gimpcolorarea.c +++ b/libgimpwidgets/gimpcolorarea.c @@ -39,10 +39,10 @@ /** * SECTION: gimpcolorarea * @title: GimpColorArea - * @short_description: Displays a #GimpRGB color, optionally with + * @short_description: Displays a [class@Gegl.Color], optionally with * alpha-channel. * - * Displays a #GimpRGB color, optionally with alpha-channel. + * Displays a [class@Gegl.Color], optionally with alpha-channel. **/ @@ -77,7 +77,7 @@ struct _GimpColorAreaPrivate guint rowstride; GimpColorAreaType type; - GimpRGB color; + GeglColor *color; guint draw_border : 1; guint needs_render : 1; @@ -108,7 +108,7 @@ static void gimp_color_area_render_buf (GtkWidget *widget, guint width, guint height, guint rowstride, - GimpRGB *color); + GeglColor *color); static void gimp_color_area_render (GimpColorArea *area); static void gimp_color_area_drag_begin (GtkWidget *widget, @@ -147,7 +147,6 @@ gimp_color_area_class_init (GimpColorAreaClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - GimpRGB color; gimp_color_area_signals[COLOR_CHANGED] = g_signal_new ("color-changed", @@ -172,7 +171,7 @@ gimp_color_area_class_init (GimpColorAreaClass *klass) klass->color_changed = NULL; - gimp_rgba_set (&color, 0.0, 0.0, 0.0, 1.0); + babl_init (); /** * GimpColorArea:color: @@ -182,12 +181,12 @@ gimp_color_area_class_init (GimpColorAreaClass *klass) * Since: 2.4 */ g_object_class_install_property (object_class, PROP_COLOR, - gimp_param_spec_rgb ("color", - "Color", - "The displayed color", - TRUE, &color, - GIMP_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); + gegl_param_spec_color_from_string ("color", + "Color", + "The displayed color", + "black", + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); /** * GimpColorArea:type: * @@ -246,6 +245,7 @@ gimp_color_area_init (GimpColorArea *area) priv->height = 0; priv->rowstride = 0; priv->draw_border = FALSE; + priv->color = gegl_color_new ("black"); gtk_drag_dest_set (GTK_WIDGET (area), GTK_DEST_DEFAULT_HIGHLIGHT | @@ -275,6 +275,7 @@ gimp_color_area_finalize (GObject *object) GimpColorAreaPrivate *priv = GET_PRIVATE (object); g_clear_pointer (&priv->buf, g_free); + g_clear_object (&priv->color); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -290,7 +291,7 @@ gimp_color_area_get_property (GObject *object, switch (property_id) { case PROP_COLOR: - g_value_set_boxed (value, &priv->color); + g_value_set_object (value, priv->color); break; case PROP_TYPE: @@ -319,7 +320,7 @@ gimp_color_area_set_property (GObject *object, switch (property_id) { case PROP_COLOR: - gimp_color_area_set_color (area, g_value_get_boxed (value)); + gimp_color_area_set_color (area, g_value_get_object (value)); break; case PROP_TYPE: @@ -380,6 +381,7 @@ gimp_color_area_draw (GtkWidget *widget, GimpColorAreaPrivate *priv = GET_PRIVATE (area); GtkStyleContext *context = gtk_widget_get_style_context (widget); cairo_surface_t *buffer; + gboolean oog = priv->out_of_gamut; if (! priv->buf) return FALSE; @@ -458,11 +460,80 @@ gimp_color_area_draw (GtkWidget *widget, cairo_paint (cr); } - if (priv->config && - ((priv->color.r < 0.0 || priv->color.r > 1.0 || - priv->color.g < 0.0 || priv->color.g > 1.0 || - priv->color.b < 0.0 || priv->color.b > 1.0) || - priv->out_of_gamut)) + if (priv->config && ! oog) + { + const Babl *format; + const Babl *space; + const Babl *ctype; + + format = gegl_color_get_format (priv->color); + space = babl_format_get_space (format); + /* XXX assuming that all components have the same type. */ + ctype = babl_format_get_type (format, 0); + + if (ctype == babl_type ("half") || + ctype == babl_type ("float") || + ctype == babl_type ("double")) + { + /* Only unbounded colors can be out-of-gamut. */ + const Babl *model; + + model = babl_format_get_model (format); + +#define CHANNEL_EPSILON 1e-3 + if (model == babl_model ("R'G'B'") || + model == babl_model ("R~G~B~") || + model == babl_model ("RGB") || + model == babl_model ("R'G'B'A") || + model == babl_model ("R~G~B~A") || + model == babl_model ("RGBA")) + { + gdouble rgb[3]; + + gegl_color_get_pixel (priv->color, babl_format_with_space ("RGB double", space), rgb); + + oog = ((rgb[0] < 0.0 && -rgb[0] > CHANNEL_EPSILON) || + (rgb[0] > 1.0 && rgb[0] - 1.0 > CHANNEL_EPSILON) || + (rgb[1] < 0.0 && -rgb[1] > CHANNEL_EPSILON) || + (rgb[1] > 1.0 && rgb[1] - 1.0 > CHANNEL_EPSILON) || + (rgb[2] < 0.0 && -rgb[2] > CHANNEL_EPSILON) || + (rgb[2] > 1.0 && rgb[2] - 1.0 > CHANNEL_EPSILON)); + } + else if (model == babl_model ("Y'") || + model == babl_model ("Y~") || + model == babl_model ("Y") || + model == babl_model ("Y'A") || + model == babl_model ("Y~A") || + model == babl_model ("YA")) + { + gdouble gray[1]; + + gegl_color_get_pixel (priv->color, babl_format_with_space ("Y double", space), gray); + oog = ((gray[0] < 0.0 && -gray[0] > CHANNEL_EPSILON) || + (gray[0] > 1.0 && gray[0] - 1.0 > CHANNEL_EPSILON)); + } + else if (model == babl_model ("CMYK") || + model == babl_model ("CMYKA") || + model == babl_model ("cmyk") || + model == babl_model ("cmykA")) + { + gdouble cmyk[4]; + + gegl_color_get_pixel (priv->color, babl_format_with_space ("CMYK double", space), cmyk); + oog = ((cmyk[0] < 0.0 && -cmyk[0] > CHANNEL_EPSILON) || + (cmyk[0] > 1.0 && cmyk[0] - 1.0 > CHANNEL_EPSILON) || + (cmyk[1] < 0.0 && -cmyk[1] > CHANNEL_EPSILON) || + (cmyk[1] > 1.0 && cmyk[1] - 1.0 > CHANNEL_EPSILON) || + (cmyk[2] < 0.0 && -cmyk[2] > CHANNEL_EPSILON) || + (cmyk[2] > 1.0 && cmyk[2] - 1.0 > CHANNEL_EPSILON) || + (cmyk[3] < 0.0 && -cmyk[3] > CHANNEL_EPSILON) || + (cmyk[3] > 1.0 && cmyk[3] - 1.0 > CHANNEL_EPSILON)); + } +#undef CHANNEL_EPSILON + } + } + + if (priv->config && oog) { GeglColor *oog_color; gint side = MIN (priv->width, priv->height) * 2 / 3; @@ -500,7 +571,7 @@ gimp_color_area_draw (GtkWidget *widget, /** * gimp_color_area_new: - * @color: A pointer to a #GimpRGB struct. + * @color: A pointer to a [class@Gegl.Color]. * @type: The type of color area to create. * @drag_mask: The event_mask that should trigger drags. * @@ -512,7 +583,7 @@ gimp_color_area_draw (GtkWidget *widget, * Returns: Pointer to the new #GimpColorArea widget. **/ GtkWidget * -gimp_color_area_new (const GimpRGB *color, +gimp_color_area_new (GeglColor *color, GimpColorAreaType type, GdkModifierType drag_mask) { @@ -526,25 +597,27 @@ gimp_color_area_new (const GimpRGB *color, /** * gimp_color_area_set_color: * @area: Pointer to a #GimpColorArea. - * @color: Pointer to a #GimpRGB struct that defines the new color. + * @color: Pointer to a [class@Gegl.Color] that defines the new color. * * Sets @area to a different @color. **/ void gimp_color_area_set_color (GimpColorArea *area, - const GimpRGB *color) + GeglColor *color) { GimpColorAreaPrivate *priv; g_return_if_fail (GIMP_IS_COLOR_AREA (area)); - g_return_if_fail (color != NULL); + g_return_if_fail (GEGL_IS_COLOR (color)); priv = GET_PRIVATE (area); - if (gimp_rgba_distance (&priv->color, color) < GIMP_RGBA_EPSILON) + if (gimp_color_is_perceptually_identical (priv->color, color)) return; - priv->color = *color; + color = gegl_color_duplicate (color); + g_clear_object (&priv->color); + priv->color = color; priv->needs_render = TRUE; gtk_widget_queue_draw (GTK_WIDGET (area)); @@ -557,23 +630,22 @@ gimp_color_area_set_color (GimpColorArea *area, /** * gimp_color_area_get_color: * @area: Pointer to a #GimpColorArea. - * @color: (out caller-allocates): Pointer to a #GimpRGB struct - * that is used to return the color. * * Retrieves the current color of the @area. + * + * Returns: (transfer full): a copy of the [class@Gegl.Color] displayed in + * @area. **/ -void -gimp_color_area_get_color (GimpColorArea *area, - GimpRGB *color) +GeglColor * +gimp_color_area_get_color (GimpColorArea *area) { GimpColorAreaPrivate *priv; - g_return_if_fail (GIMP_IS_COLOR_AREA (area)); - g_return_if_fail (color != NULL); + g_return_val_if_fail (GIMP_IS_COLOR_AREA (area), NULL); priv = GET_PRIVATE (area); - *color = priv->color; + return gegl_color_duplicate (priv->color); } /** @@ -763,15 +835,18 @@ gimp_color_area_render_buf (GtkWidget *widget, guint width, guint height, guint rowstride, - GimpRGB *color) + GeglColor *color) { - guint x, y; - guint check_size = 0; - guchar light[3]; - guchar dark[3]; - guchar opaque[3]; - guchar *p; - gdouble frac; + GimpColorAreaPrivate *priv = GET_PRIVATE (widget); + const Babl *render_space; + guint x, y; + guint check_size = 0; + guchar light[3]; + guchar dark[3]; + gdouble opaque_d[4]; + guchar opaque[4]; + guchar *p; + gdouble frac; switch (type) { @@ -788,9 +863,11 @@ gimp_color_area_render_buf (GtkWidget *widget, break; } - gimp_rgb_get_uchar (color, opaque, opaque + 1, opaque + 2); + render_space = gimp_widget_get_render_space (widget, priv->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 double", render_space), opaque_d); - if (check_size == 0 || color->a == 1.0) + if (check_size == 0 || opaque_d[3] == 1.0) { for (y = 0; y < height; y++) { @@ -811,19 +888,22 @@ gimp_color_area_render_buf (GtkWidget *widget, } light[0] = (GIMP_CHECK_LIGHT + - (color->r - GIMP_CHECK_LIGHT) * color->a) * 255.999; + (opaque_d[0] - GIMP_CHECK_LIGHT) * opaque_d[3]) * 255.999; light[1] = (GIMP_CHECK_LIGHT + - (color->g - GIMP_CHECK_LIGHT) * color->a) * 255.999; + (opaque_d[1] - GIMP_CHECK_LIGHT) * opaque_d[3]) * 255.999; light[2] = (GIMP_CHECK_LIGHT + - (color->b - GIMP_CHECK_LIGHT) * color->a) * 255.999; + (opaque_d[2] - GIMP_CHECK_LIGHT) * opaque_d[3]) * 255.999; dark[0] = (GIMP_CHECK_DARK + - (color->r - GIMP_CHECK_DARK) * color->a) * 255.999; + (opaque_d[0] - GIMP_CHECK_DARK) * opaque_d[3]) * 255.999; dark[1] = (GIMP_CHECK_DARK + - (color->g - GIMP_CHECK_DARK) * color->a) * 255.999; + (opaque_d[1] - GIMP_CHECK_DARK) * opaque_d[3]) * 255.999; dark[2] = (GIMP_CHECK_DARK + - (color->b - GIMP_CHECK_DARK) * color->a) * 255.999; + (opaque_d[2] - GIMP_CHECK_DARK) * opaque_d[3]) * 255.999; + /* TODO: should we get float data and render in CAIRO_FORMAT_RGBA128F rather + * than in CAIRO_FORMAT_RGB24? + */ for (y = 0; y < height; y++) { p = buf + y * rowstride; @@ -901,7 +981,7 @@ gimp_color_area_render (GimpColorArea *area) priv->type, priv->buf, priv->width, priv->height, priv->rowstride, - &priv->color); + priv->color); priv->needs_render = FALSE; } @@ -911,7 +991,7 @@ gimp_color_area_drag_begin (GtkWidget *widget, GdkDragContext *context) { GimpColorAreaPrivate *priv = GET_PRIVATE (widget); - GimpRGB color; + GeglColor *color; GtkWidget *window; GtkWidget *frame; GtkWidget *color_area; @@ -926,9 +1006,9 @@ gimp_color_area_drag_begin (GtkWidget *widget, gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); gtk_container_add (GTK_CONTAINER (window), frame); - gimp_color_area_get_color (GIMP_COLOR_AREA (widget), &color); - - color_area = gimp_color_area_new (&color, priv->type, 0); + color = gimp_color_area_get_color (GIMP_COLOR_AREA (widget)); + color_area = gimp_color_area_new (color, priv->type, 0); + g_object_unref (color); gtk_widget_set_size_request (color_area, DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE); @@ -964,7 +1044,8 @@ gimp_color_area_drag_data_received (GtkWidget *widget, { GimpColorArea *area = GIMP_COLOR_AREA (widget); const guint16 *vals; - GimpRGB color; + GeglColor *color; + GimpRGB rgb; if (gtk_selection_data_get_length (selection_data) != 8 || gtk_selection_data_get_format (selection_data) != 16) @@ -975,13 +1056,17 @@ gimp_color_area_drag_data_received (GtkWidget *widget, vals = (const guint16 *) gtk_selection_data_get_data (selection_data); - gimp_rgba_set (&color, + gimp_rgba_set (&rgb, (gdouble) vals[0] / 0xffff, (gdouble) vals[1] / 0xffff, (gdouble) vals[2] / 0xffff, (gdouble) vals[3] / 0xffff); + color = gegl_color_new (NULL); + gegl_color_set_pixel (color, babl_format ("R'G'B' double"), &rgb); - gimp_color_area_set_color (area, &color); + gimp_color_area_set_color (area, color); + + g_object_unref (color); } static void @@ -992,16 +1077,18 @@ gimp_color_area_drag_data_get (GtkWidget *widget, guint time) { GimpColorAreaPrivate *priv = GET_PRIVATE (widget); + gdouble rgb[4]; guint16 vals[4]; - vals[0] = priv->color.r * 0xffff; - vals[1] = priv->color.g * 0xffff; - vals[2] = priv->color.b * 0xffff; + gegl_color_get_pixel (priv->color, babl_format_with_space ("R'G'B'A double", NULL), rgb); + vals[0] = rgb[0] * 0xffff; + vals[1] = rgb[1] * 0xffff; + vals[2] = rgb[2] * 0xffff; if (priv->type == GIMP_COLOR_AREA_FLAT) vals[3] = 0xffff; else - vals[3] = priv->color.a * 0xffff; + vals[3] = rgb[3] * 0xffff; gtk_selection_data_set (selection_data, gdk_atom_intern ("application/x-color", FALSE), diff --git a/libgimpwidgets/gimpcolorarea.h b/libgimpwidgets/gimpcolorarea.h index 09d01b6b63..bc7b7bdb68 100644 --- a/libgimpwidgets/gimpcolorarea.h +++ b/libgimpwidgets/gimpcolorarea.h @@ -72,14 +72,13 @@ struct _GimpColorAreaClass GType gimp_color_area_get_type (void) G_GNUC_CONST; -GtkWidget * gimp_color_area_new (const GimpRGB *color, +GtkWidget * gimp_color_area_new (GeglColor *color, GimpColorAreaType type, GdkModifierType drag_mask); void gimp_color_area_set_color (GimpColorArea *area, - const GimpRGB *color); -void gimp_color_area_get_color (GimpColorArea *area, - GimpRGB *color); + GeglColor *color); +GeglColor * gimp_color_area_get_color (GimpColorArea *area); gboolean gimp_color_area_has_alpha (GimpColorArea *area); void gimp_color_area_set_type (GimpColorArea *area, diff --git a/libgimpwidgets/gimpcolorbutton.c b/libgimpwidgets/gimpcolorbutton.c index a6feb921c8..68d9cd638c 100644 --- a/libgimpwidgets/gimpcolorbutton.c +++ b/libgimpwidgets/gimpcolorbutton.c @@ -711,16 +711,20 @@ gimp_color_button_get_title (GimpColorButton *button) **/ void gimp_color_button_set_color (GimpColorButton *button, - const GimpRGB *color) + const GimpRGB *rgb) { GimpColorButtonPrivate *priv; + GeglColor *color; g_return_if_fail (GIMP_IS_COLOR_BUTTON (button)); - g_return_if_fail (color != NULL); + g_return_if_fail (rgb != NULL); priv = GET_PRIVATE (button); + color = gegl_color_new (NULL); + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), rgb); gimp_color_area_set_color (GIMP_COLOR_AREA (priv->color_area), color); + g_object_unref (color); g_object_notify (G_OBJECT (button), "color"); } @@ -735,16 +739,19 @@ gimp_color_button_set_color (GimpColorButton *button, **/ void gimp_color_button_get_color (GimpColorButton *button, - GimpRGB *color) + GimpRGB *rgb) { GimpColorButtonPrivate *priv; + GeglColor *color; g_return_if_fail (GIMP_IS_COLOR_BUTTON (button)); - g_return_if_fail (color != NULL); + g_return_if_fail (rgb != NULL); priv = GET_PRIVATE (button); - gimp_color_area_get_color (GIMP_COLOR_AREA (priv->color_area), color); + color = gimp_color_area_get_color (GIMP_COLOR_AREA (priv->color_area)); + gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), rgb); + g_object_unref (color); } /** @@ -1034,15 +1041,19 @@ gimp_color_button_selection_changed (GtkWidget *selection, if (priv->continuous_update) { - GimpRGB color; + GeglColor *color; + GimpRGB rgb; - gimp_color_selection_get_color (GIMP_COLOR_SELECTION (selection), &color); + gimp_color_selection_get_color (GIMP_COLOR_SELECTION (selection), &rgb); g_signal_handlers_block_by_func (priv->color_area, gimp_color_button_area_changed, button); - gimp_color_area_set_color (GIMP_COLOR_AREA (priv->color_area), &color); + color = gegl_color_new (NULL); + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), &rgb); + gimp_color_area_set_color (GIMP_COLOR_AREA (priv->color_area), color); + g_object_unref (color); g_signal_handlers_unblock_by_func (priv->color_area, gimp_color_button_area_changed, diff --git a/libgimpwidgets/gimpcolorselection.c b/libgimpwidgets/gimpcolorselection.c index 6ae29a44d4..168a0ecd2a 100644 --- a/libgimpwidgets/gimpcolorselection.c +++ b/libgimpwidgets/gimpcolorselection.c @@ -181,6 +181,7 @@ gimp_color_selection_init (GimpColorSelection *selection) GtkWidget *button; GtkSizeGroup *new_group; GtkSizeGroup *old_group; + GeglColor *color; selection->priv = gimp_color_selection_get_instance_private (selection); @@ -272,7 +273,9 @@ gimp_color_selection_init (GimpColorSelection *selection) gtk_container_add (GTK_CONTAINER (frame), vbox); gtk_widget_show (vbox); - priv->new_color = gimp_color_area_new (&priv->rgb, + color = gegl_color_new (NULL); + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), &priv->rgb); + priv->new_color = gimp_color_area_new (color, priv->show_alpha ? GIMP_COLOR_AREA_SMALL_CHECKS : GIMP_COLOR_AREA_FLAT, @@ -286,7 +289,7 @@ gimp_color_selection_init (GimpColorSelection *selection) G_CALLBACK (gimp_color_selection_new_color_changed), selection); - priv->old_color = gimp_color_area_new (&priv->rgb, + priv->old_color = gimp_color_area_new (color, priv->show_alpha ? GIMP_COLOR_AREA_SMALL_CHECKS : GIMP_COLOR_AREA_FLAT, @@ -350,6 +353,8 @@ gimp_color_selection_init (GimpColorSelection *selection) g_signal_connect (entry, "color-changed", G_CALLBACK (gimp_color_selection_entry_changed), selection); + + g_object_unref (color); } static void @@ -492,16 +497,20 @@ gimp_color_selection_get_color (GimpColorSelection *selection, **/ void gimp_color_selection_set_old_color (GimpColorSelection *selection, - const GimpRGB *color) + const GimpRGB *rgb) { GimpColorSelectionPrivate *priv; + GeglColor *color; g_return_if_fail (GIMP_IS_COLOR_SELECTION (selection)); - g_return_if_fail (color != NULL); + g_return_if_fail (rgb != NULL); priv = GET_PRIVATE (selection); + color = gegl_color_new (NULL); + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), rgb); gimp_color_area_set_color (GIMP_COLOR_AREA (priv->old_color), color); + g_object_unref (color); } /** @@ -514,16 +523,19 @@ gimp_color_selection_set_old_color (GimpColorSelection *selection, **/ void gimp_color_selection_get_old_color (GimpColorSelection *selection, - GimpRGB *color) + GimpRGB *rgb) { GimpColorSelectionPrivate *priv; + GeglColor *color; g_return_if_fail (GIMP_IS_COLOR_SELECTION (selection)); - g_return_if_fail (color != NULL); + g_return_if_fail (rgb != NULL); priv = GET_PRIVATE (selection); - gimp_color_area_get_color (GIMP_COLOR_AREA (priv->old_color), color); + color = gimp_color_area_get_color (GIMP_COLOR_AREA (priv->old_color)); + gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), rgb); + g_object_unref (color); } /** @@ -536,14 +548,18 @@ void gimp_color_selection_reset (GimpColorSelection *selection) { GimpColorSelectionPrivate *priv; - GimpRGB color; + GeglColor *color; + GimpRGB rgb; g_return_if_fail (GIMP_IS_COLOR_SELECTION (selection)); priv = GET_PRIVATE (selection); - gimp_color_area_get_color (GIMP_COLOR_AREA (priv->old_color), &color); - gimp_color_selection_set_color (selection, &color); + color = gimp_color_area_get_color (GIMP_COLOR_AREA (priv->old_color)); + gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &rgb); + gimp_color_selection_set_color (selection, &rgb); + + g_object_unref (color); } /** @@ -745,13 +761,17 @@ gimp_color_selection_new_color_changed (GtkWidget *widget, GimpColorSelection *selection) { GimpColorSelectionPrivate *priv = GET_PRIVATE (selection); + GeglColor *color; - gimp_color_area_get_color (GIMP_COLOR_AREA (widget), &priv->rgb); - gimp_rgb_to_hsv (&priv->rgb, &priv->hsv); + color = gimp_color_area_get_color (GIMP_COLOR_AREA (widget)); + gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &priv->rgb); + gegl_color_get_pixel (color, babl_format ("HSVA double"), &priv->hsv); gimp_color_selection_update (selection, UPDATE_NOTEBOOK | UPDATE_SCALES | UPDATE_ENTRY); gimp_color_selection_color_changed (selection); + + g_object_unref (color); } static void @@ -809,15 +829,20 @@ gimp_color_selection_update (GimpColorSelection *selection, if (update & UPDATE_COLOR) { + GeglColor *color; + g_signal_handlers_block_by_func (priv->new_color, gimp_color_selection_new_color_changed, selection); - gimp_color_area_set_color (GIMP_COLOR_AREA (priv->new_color), - &priv->rgb); + color = gegl_color_new (NULL); + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), &priv->rgb); + gimp_color_area_set_color (GIMP_COLOR_AREA (priv->new_color), color); g_signal_handlers_unblock_by_func (priv->new_color, gimp_color_selection_new_color_changed, selection); + + g_object_unref (color); } } diff --git a/libgimpwidgets/gimplabelcolor.c b/libgimpwidgets/gimplabelcolor.c index e12364cde6..7cbc9e25cb 100644 --- a/libgimpwidgets/gimplabelcolor.c +++ b/libgimpwidgets/gimplabelcolor.c @@ -148,18 +148,19 @@ gimp_label_color_class_init (GimpLabelColorClass *klass) static void gimp_label_color_init (GimpLabelColor *color) { - GimpLabelColorPrivate *priv = gimp_label_color_get_instance_private (color); - GimpRGB black; + GimpLabelColorPrivate *priv = gimp_label_color_get_instance_private (color); + GeglColor *black = gegl_color_new ("black"); - gimp_rgba_set (&black, 0.0, 0.0, 0.0, 1.0); priv->editable = FALSE; - priv->area = gimp_color_area_new (&black, GIMP_COLOR_AREA_SMALL_CHECKS, + priv->area = gimp_color_area_new (black, GIMP_COLOR_AREA_SMALL_CHECKS, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK); /* Typically for a labelled color area, a small square next to your * label is probably what you want to display. */ gtk_widget_set_size_request (priv->area, 20, 20); + + g_object_unref (black); } static void @@ -224,7 +225,7 @@ gimp_label_color_set_property (GObject *object, { const gchar *dialog_title; GimpLabeled *labeled; - GimpRGB *rgb; + GeglColor *color; GimpColorAreaType type; gboolean attached; @@ -238,18 +239,20 @@ gimp_label_color_set_property (GObject *object, attached = (gtk_widget_get_parent (priv->area) != NULL); g_object_get (priv->area, "type", &type, - "color", &rgb, + "color", &color, NULL); gtk_widget_destroy (priv->area); priv->editable = g_value_get_boolean (value); + if (priv->editable) priv->area = gimp_color_button_new (dialog_title, - 20, 20, rgb, type); + 20, 20, color, type); else - priv->area = gimp_color_area_new (rgb, type, + priv->area = gimp_color_area_new (color, type, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK); + g_object_unref (color); gtk_widget_set_size_request (priv->area, 20, 20); g_object_bind_property_full (G_OBJECT (priv->area), "color", diff --git a/libgimpwidgets/gimppropwidgets.c b/libgimpwidgets/gimppropwidgets.c index f52e7c7245..adc7f2cf94 100644 --- a/libgimpwidgets/gimppropwidgets.c +++ b/libgimpwidgets/gimppropwidgets.c @@ -4090,8 +4090,7 @@ gimp_prop_color_area_new (GObject *config, { GParamSpec *param_spec; GtkWidget *area; - GeglColor *value = NULL; - GimpRGB rgb = { 0 }; + GeglColor *color = NULL; param_spec = check_param_spec_w (config, property_name, GEGL_TYPE_PARAM_COLOR, G_STRFUNC); @@ -4099,16 +4098,13 @@ gimp_prop_color_area_new (GObject *config, return NULL; g_object_get (config, - property_name, &value, + property_name, &color, NULL); - if (value != NULL) - gegl_color_get_pixel (value, babl_format ("R'G'B'A double"), &rgb); - area = gimp_color_area_new (&rgb, type, - GDK_BUTTON1_MASK | GDK_BUTTON2_MASK); + area = gimp_color_area_new (color, type, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK); gtk_widget_set_size_request (area, width, height); - g_clear_object (&value); + g_clear_object (&color); set_param_spec (G_OBJECT (area), area, param_spec); @@ -4133,15 +4129,12 @@ gimp_prop_color_area_callback (GtkWidget *area, { GParamSpec *param_spec; GeglColor *color; - GimpRGB value; param_spec = get_param_spec (G_OBJECT (area)); if (! param_spec) return; - color = gegl_color_new (NULL); - gimp_color_area_get_color (GIMP_COLOR_AREA (area), &value); - gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), &value); + color = gimp_color_area_get_color (GIMP_COLOR_AREA (area)); g_signal_handlers_block_by_func (config, gimp_prop_color_area_notify, @@ -4163,7 +4156,6 @@ gimp_prop_color_area_notify (GObject *config, GtkWidget *area) { GeglColor *color = NULL; - GimpRGB value; g_object_get (config, param_spec->name, &color, @@ -4173,8 +4165,7 @@ gimp_prop_color_area_notify (GObject *config, gimp_prop_color_area_callback, config); - gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &value); - gimp_color_area_set_color (GIMP_COLOR_AREA (area), &value); + gimp_color_area_set_color (GIMP_COLOR_AREA (area), color); g_clear_object (&color); diff --git a/libgimpwidgets/gimpwidgets.def b/libgimpwidgets/gimpwidgets.def index 7cc0a83c82..09609d511c 100644 --- a/libgimpwidgets/gimpwidgets.def +++ b/libgimpwidgets/gimpwidgets.def @@ -498,6 +498,7 @@ EXPORTS gimp_widget_get_color_profile gimp_widget_get_color_transform gimp_widget_get_monitor + gimp_widget_get_render_space gimp_widget_set_bound_property gimp_widget_set_identifier gimp_widget_set_native_handle diff --git a/libgimpwidgets/gimpwidgetsutils.c b/libgimpwidgets/gimpwidgetsutils.c index 147c1f23d6..eb87615f60 100644 --- a/libgimpwidgets/gimpwidgetsutils.c +++ b/libgimpwidgets/gimpwidgetsutils.c @@ -1055,6 +1055,47 @@ gimp_widget_get_color_transform (GtkWidget *widget, return NULL; } +/** + * gimp_widget_get_render_format: + * @widget: (nullable): [class@Gtk.Widget] to draw the focus indicator on. + * @config: the color management settings. + * @softproof: whether the color must also be soft-proofed. + * + * Gets the Babl format to use as target format when rendering raw data on + * @widget. The format model with be "R'G'B'A" and the component types will be + * double. + * + * If @config is set, the color configuration as set by the user will be used, + * in particular using any custom monitor profile set in preferences (overriding + * system-set profile). If no such custom profile is set, it will use the + * profile of the monitor @widget is displayed on and will default to sRGB if + * @widget is %NULL. + * + * Use [func@Gimp.get_color_configuration] to retrieve the user + * [class@Gimp.ColorConfig]. + * + * TODO: @softproof is currently unused. + * + * Since: 3.0 + **/ +const Babl * +gimp_widget_get_render_space (GtkWidget *widget, + GimpColorConfig *config) +{ + GimpColorProfile *dest_profile = NULL; + const Babl *space = NULL; + + g_return_val_if_fail (widget == NULL || GTK_IS_WIDGET (widget), NULL); + + _gimp_widget_get_profiles (widget, config, NULL, &dest_profile); + + if (dest_profile) + space = gimp_color_profile_get_space (dest_profile, + GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC, + NULL); + return space; +} + /** * gimp_widget_set_native_handle: * @widget: a #GtkWindow diff --git a/libgimpwidgets/gimpwidgetsutils.h b/libgimpwidgets/gimpwidgetsutils.h index e715bd82d4..4ade052aaf 100644 --- a/libgimpwidgets/gimpwidgetsutils.h +++ b/libgimpwidgets/gimpwidgetsutils.h @@ -64,17 +64,19 @@ GimpColorTransform * gimp_widget_get_color_transform (GtkWidget *widget, GimpColorProfile *softproof_profile, GimpColorRenderingIntent proof_intent, gboolean proof_bpc); +const Babl * gimp_widget_get_render_space (GtkWidget *widget, + GimpColorConfig *config); -void gimp_widget_set_native_handle (GtkWidget *widget, - GBytes **handle); +void gimp_widget_set_native_handle (GtkWidget *widget, + GBytes **handle); /* Internal use */ -G_GNUC_INTERNAL void _gimp_widget_get_profiles (GtkWidget *widget, - GimpColorConfig *config, - GimpColorProfile **proof_profile, - GimpColorProfile **dest_profile); +G_GNUC_INTERNAL void _gimp_widget_get_profiles (GtkWidget *widget, + GimpColorConfig *config, + GimpColorProfile **proof_profile, + GimpColorProfile **dest_profile); G_END_DECLS diff --git a/plug-ins/ifs-compose/ifs-compose.c b/plug-ins/ifs-compose/ifs-compose.c index 593e5a4444..53d35b5fd3 100644 --- a/plug-ins/ifs-compose/ifs-compose.c +++ b/plug-ins/ifs-compose/ifs-compose.c @@ -2020,6 +2020,7 @@ color_map_create (const gchar *name, GtkWidget *frame; GtkWidget *arrow; ColorMap *color_map = g_new (ColorMap, 1); + GeglColor *color; gimp_rgb_set_alpha (data, 1.0); color_map->color = data; @@ -2031,9 +2032,10 @@ color_map_create (const gchar *name, gtk_box_pack_start (GTK_BOX (color_map->hbox), frame, FALSE, FALSE, 0); gtk_widget_show (frame); - color_map->orig_preview = - gimp_color_area_new (fixed_point ? data : orig_color, - GIMP_COLOR_AREA_FLAT, 0); + color = gegl_color_new (NULL); + gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), fixed_point ? data : orig_color); + color_map->orig_preview = gimp_color_area_new (color, GIMP_COLOR_AREA_FLAT, 0); + g_object_unref (color); gtk_drag_dest_unset (color_map->orig_preview); gtk_widget_set_size_request (color_map->orig_preview, COLOR_SAMPLE_SIZE, COLOR_SAMPLE_SIZE); @@ -2091,8 +2093,14 @@ color_map_update (ColorMap *color_map) color_map->color); if (color_map->fixed_point) - gimp_color_area_set_color (GIMP_COLOR_AREA (color_map->orig_preview), - color_map->color); + { + GeglColor *color; + + color = gegl_color_new (NULL); + gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), color_map->color); + gimp_color_area_set_color (GIMP_COLOR_AREA (color_map->orig_preview), color); + g_object_unref (color); + } } static void