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().
This commit is contained in:
Jehan
2023-11-23 22:08:09 +01:00
parent 5a0f88e053
commit 8eb56586aa
21 changed files with 392 additions and 195 deletions

View File

@ -216,7 +216,7 @@ item_options_dialog_new (GimpImage *image,
list = g_list_next (list)) list = g_list_next (list))
{ {
GimpColorTag color_tag; GimpColorTag color_tag;
GimpRGB color; GimpRGB rgb;
GtkWidget *image; GtkWidget *image;
radio = list->data; 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), color_tag = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (radio),
"gimp-item-data")); "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), gimp_color_area_set_color_config (GIMP_COLOR_AREA (image),
context->gimp->config->color_management); context->gimp->config->color_management);
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h); gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
gtk_widget_set_size_request (image, w, h); gtk_widget_set_size_request (image, w, h);
g_object_unref (color);
} }
else else
{ {

View File

@ -50,7 +50,8 @@ hue_saturation_config_notify (GObject *object,
{ {
GimpHueSaturationConfig *config = GIMP_HUE_SATURATION_CONFIG (object); GimpHueSaturationConfig *config = GIMP_HUE_SATURATION_CONFIG (object);
GimpHueRange range; GimpHueRange range;
GimpRGB color; GeglColor *color;
GimpRGB rgb;
static const GimpRGB default_colors[7] = 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), range = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (color_area),
"hue-range")); "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 static void
@ -189,7 +193,7 @@ _gimp_prop_gui_new_hue_saturation (GObject *config,
if (i > 0) if (i > 0)
{ {
GtkWidget *color_area; GtkWidget *color_area;
GimpRGB color = { 0, }; GeglColor *color = gegl_color_new ("transparent");
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); 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); 1, 1);
gtk_widget_show (frame); 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_widget_set_size_request (color_area, COLOR_WIDTH, COLOR_HEIGHT);
gtk_container_add (GTK_CONTAINER (frame), color_area); gtk_container_add (GTK_CONTAINER (frame), color_area);
gtk_widget_show (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), G_CALLBACK (hue_saturation_config_notify),
color_area, 0); color_area, 0);
hue_saturation_config_notify (config, NULL, color_area); hue_saturation_config_notify (config, NULL, color_area);
g_object_unref (color);
} }
g_signal_connect (button, "toggled", g_signal_connect (button, "toggled",

View File

@ -339,7 +339,7 @@ gimp_color_picker_tool_info_create (GimpColorPickerTool *picker_tool,
GList *drawables = gimp_image_get_selected_drawables (image); GList *drawables = gimp_image_get_selected_drawables (image);
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *frame; GtkWidget *frame;
GimpRGB color; GeglColor *color;
picker_tool->gui = gimp_tool_gui_new (tool->tool_info, picker_tool->gui = gimp_tool_gui_new (tool->tool_info,
NULL, 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_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame); 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 = picker_tool->color_area =
gimp_color_area_new (&color, gimp_color_area_new (color,
drawables && gimp_drawable_has_alpha (drawables->data) ? drawables && gimp_drawable_has_alpha (drawables->data) ?
GIMP_COLOR_AREA_LARGE_CHECKS : GIMP_COLOR_AREA_LARGE_CHECKS :
GIMP_COLOR_AREA_FLAT, GIMP_COLOR_AREA_FLAT,
@ -410,6 +410,7 @@ gimp_color_picker_tool_info_create (GimpColorPickerTool *picker_tool,
gtk_widget_show (picker_tool->color_area); gtk_widget_show (picker_tool->color_area);
g_list_free (drawables); g_list_free (drawables);
g_object_unref (color);
} }
static void static void
@ -435,7 +436,6 @@ gimp_color_picker_tool_info_update (GimpColorPickerTool *picker_tool,
GimpTool *tool = GIMP_TOOL (picker_tool); GimpTool *tool = GIMP_TOOL (picker_tool);
GimpImage *image = gimp_display_get_image (display); GimpImage *image = gimp_display_get_image (display);
GList *drawables = gimp_image_get_selected_drawables (image); GList *drawables = gimp_image_get_selected_drawables (image);
GimpRGB rgb;
tool->display = display; 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); gimp_tool_gui_set_viewables (picker_tool->gui, drawables);
g_list_free (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), color);
gimp_color_area_set_color (GIMP_COLOR_AREA (picker_tool->color_area), &rgb);
gimp_color_frame_set_color (GIMP_COLOR_FRAME (picker_tool->color_frame1), gimp_color_frame_set_color (GIMP_COLOR_FRAME (picker_tool->color_frame1),
sample_average, color, x, y); sample_average, color, x, y);
gimp_color_frame_set_color (GIMP_COLOR_FRAME (picker_tool->color_frame2), gimp_color_frame_set_color (GIMP_COLOR_FRAME (picker_tool->color_frame2),

View File

@ -1009,22 +1009,26 @@ gimp_action_set_proxy (GimpAction *action,
{ {
if (priv->color) if (priv->color)
{ {
GeglColor *color;
if (GTK_IS_MENU_ITEM (proxy)) if (GTK_IS_MENU_ITEM (proxy))
proxy_image = gimp_menu_item_get_image (GTK_MENU_ITEM (proxy)); proxy_image = gimp_menu_item_get_image (GTK_MENU_ITEM (proxy));
else else
proxy_image = gtk_tool_button_get_label_widget (GTK_TOOL_BUTTON (proxy)); 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)) 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; proxy_image = NULL;
} }
else else
{ {
gint width, height; gint width, height;
proxy_image = gimp_color_area_new (priv->color, proxy_image = gimp_color_area_new (color, GIMP_COLOR_AREA_SMALL_CHECKS, 0);
GIMP_COLOR_AREA_SMALL_CHECKS, 0);
gimp_color_area_set_draw_border (GIMP_COLOR_AREA (proxy_image), TRUE); gimp_color_area_set_draw_border (GIMP_COLOR_AREA (proxy_image), TRUE);
if (priv->context) if (priv->context)
@ -1035,6 +1039,8 @@ gimp_action_set_proxy (GimpAction *action,
gtk_widget_set_size_request (proxy_image, width, height); gtk_widget_set_size_request (proxy_image, width, height);
gtk_widget_show (proxy_image); gtk_widget_show (proxy_image);
} }
g_object_unref (color);
} }
else if (priv->viewable) else if (priv->viewable)
{ {

View File

@ -190,7 +190,7 @@ gimp_color_frame_init (GimpColorFrame *frame)
frame->color_area = frame->color_area =
g_object_new (GIMP_TYPE_COLOR_AREA, g_object_new (GIMP_TYPE_COLOR_AREA,
"color", &frame->color, "color", frame->color,
"type", GIMP_COLOR_AREA_SMALL_CHECKS, "type", GIMP_COLOR_AREA_SMALL_CHECKS,
"drag-mask", GDK_BUTTON1_MASK, "drag-mask", GDK_BUTTON1_MASK,
"draw-border", TRUE, "draw-border", TRUE,
@ -755,11 +755,9 @@ gimp_color_frame_update (GimpColorFrame *frame)
if (frame->sample_valid) 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), frame->color);
gimp_color_area_set_color (GIMP_COLOR_AREA (frame->color_area), &rgb);
g_snprintf (str, sizeof (str), "%d", frame->x); g_snprintf (str, sizeof (str), "%d", frame->x);
gtk_label_set_text (GTK_LABEL (frame->coords_label_x), str); 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; const Babl *print_format;
gfloat grayscale[2]; gfloat grayscale[2];
GimpRGB grayscale_color; GeglColor *grayscale_color;
print_format = gimp_babl_format (GIMP_GRAY, print_format = gimp_babl_format (GIMP_GRAY,
gimp_babl_precision (GIMP_COMPONENT_TYPE_FLOAT, trc), 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 /* Change color area color to grayscale if image is not
* in Grayscale Mode */ * in Grayscale Mode */
gimp_rgba_set (&grayscale_color, grayscale[0], grayscale[0], grayscale_color = gegl_color_duplicate (frame->color);
grayscale[0], GIMP_OPACITY_OPAQUE); gegl_color_set_pixel (grayscale_color, print_format, grayscale);
gimp_color_area_set_color (GIMP_COLOR_AREA (frame->color_area), gimp_color_set_alpha (grayscale_color, GIMP_OPACITY_OPAQUE);
&grayscale_color); gimp_color_area_set_color (GIMP_COLOR_AREA (frame->color_area), grayscale_color);
g_object_unref (grayscale_color);
values = g_new0 (gchar *, 5); values = g_new0 (gchar *, 5);

View File

@ -263,8 +263,8 @@ gimp_color_history_set_property (GObject *object,
for (i = 0; i < history->history_size; i++) for (i = 0; i < history->history_size; i++)
{ {
GimpRGB black = { 0.0, 0.0, 0.0, 1.0 }; GeglColor *black = gegl_color_new ("black");
gint row, column; gint row, column;
column = i % (history->history_size / history->n_rows); column = i % (history->history_size / history->n_rows);
row = 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_grid_attach (GTK_GRID (history), button, column, row, 1, 1);
gtk_widget_show (button); 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); GDK_BUTTON2_MASK);
gimp_color_area_set_color_config (GIMP_COLOR_AREA (color_area), gimp_color_area_set_color_config (GIMP_COLOR_AREA (color_area),
history->context->gimp->config->color_management); history->context->gimp->config->color_management);
@ -291,6 +291,8 @@ gimp_color_history_set_property (GObject *object,
history->buttons[i] = button; history->buttons[i] = button;
history->color_areas[i] = color_area; history->color_areas[i] = color_area;
g_object_unref (black);
} }
gimp_color_history_palette_dirty (history); gimp_color_history_palette_dirty (history);
@ -456,14 +458,16 @@ gimp_color_history_color_clicked (GtkWidget *widget,
GimpColorHistory *history) GimpColorHistory *history)
{ {
GimpColorArea *color_area; GimpColorArea *color_area;
GimpRGB color; GeglColor *color;
GimpRGB rgb;
color_area = GIMP_COLOR_AREA (gtk_bin_get_child (GTK_BIN (widget))); 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, g_signal_emit (history, history_signals[COLOR_SELECTED], 0, &rgb);
&color);
} }
/* Color history palette callback. */ /* Color history palette callback. */
@ -496,10 +500,9 @@ gimp_color_history_palette_dirty (GimpColorHistory *history)
gimp_color_history_color_changed, gimp_color_history_color_changed,
GINT_TO_POINTER (i)); 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); 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 */ if (/* Common out-of-gamut case */
(rgb.r < 0.0 || rgb.r > 1.0 || (rgb.r < 0.0 || rgb.r > 1.0 ||
rgb.g < 0.0 || rgb.g > 1.0 || rgb.g < 0.0 || rgb.g > 1.0 ||
@ -530,16 +533,19 @@ gimp_color_history_color_changed (GtkWidget *widget,
{ {
GimpColorHistory *history; GimpColorHistory *history;
GimpPalette *palette; GimpPalette *palette;
GimpRGB color; GeglColor *color;
GimpRGB rgb;
history = GIMP_COLOR_HISTORY (gtk_widget_get_ancestor (widget, history = GIMP_COLOR_HISTORY (gtk_widget_get_ancestor (widget,
GIMP_TYPE_COLOR_HISTORY)); GIMP_TYPE_COLOR_HISTORY));
palette = gimp_palettes_get_color_history (history->context->gimp); 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 static void

View File

@ -2905,8 +2905,10 @@ gimp_dashboard_update_group (GimpDashboard *dashboard,
if (group_info->has_meter && field_info->meter_value) if (group_info->has_meter && field_info->meter_value)
{ {
color_area = gimp_color_area_new (&variable_info->color, GeglColor *color = gegl_color_new (NULL);
GIMP_COLOR_AREA_FLAT, 0);
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, gimp_help_set_help_data (color_area, description,
NULL); NULL);
gtk_widget_set_size_request (color_area, 5, 5); 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, gtk_grid_attach (group_data->grid, color_area,
0, n_rows, 1, 1); 0, n_rows, 1, 1);
gtk_widget_show (color_area); gtk_widget_show (color_area);
g_object_unref (color);
} }
str = g_strdup_printf ("%s:", str = g_strdup_printf ("%s:",

View File

@ -1387,22 +1387,27 @@ gimp_dnd_get_color_icon (GtkWidget *widget,
gpointer get_color_data) gpointer get_color_data)
{ {
GtkWidget *color_area; 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"); GIMP_LOG (DND, "called");
g_object_set_data_full (G_OBJECT (context), 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); (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), gimp_color_area_set_color_config (GIMP_COLOR_AREA (color_area),
the_dnd_gimp->config->color_management); the_dnd_gimp->config->color_management);
gtk_widget_set_size_request (color_area, gtk_widget_set_size_request (color_area,
DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE); DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE);
g_object_unref (color);
return color_area; return color_area;
} }

View File

@ -314,9 +314,9 @@ gimp_gradient_editor_init (GimpGradientEditor *editor)
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *hint_vbox; 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 for gradient view and gradient control */
frame = gtk_frame_new (NULL); 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_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame); 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, GIMP_COLOR_AREA_SMALL_CHECKS,
GDK_BUTTON1_MASK | GDK_BUTTON1_MASK |
GDK_BUTTON2_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[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[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); gimp_rgba_set (&editor->saved_colors[9], 1.0, 0.0, 1.0, GIMP_OPACITY_OPAQUE);
g_object_unref (transp);
} }
static void static void
@ -1283,6 +1285,7 @@ view_set_hint (GimpGradientEditor *editor,
gint x) gint x)
{ {
GimpDataEditor *data_editor = GIMP_DATA_EDITOR (editor); GimpDataEditor *data_editor = GIMP_DATA_EDITOR (editor);
GeglColor *color = gegl_color_new ("black");
GimpRGB rgb; GimpRGB rgb;
GimpHSV hsv; GimpHSV hsv;
gdouble xpos; gdouble xpos;
@ -1297,7 +1300,8 @@ view_set_hint (GimpGradientEditor *editor,
data_editor->context, NULL, data_editor->context, NULL,
xpos, FALSE, FALSE, &rgb); 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); gimp_rgb_to_hsv (&rgb, &hsv);
@ -1312,6 +1316,7 @@ view_set_hint (GimpGradientEditor *editor,
gradient_editor_set_hint (editor, str1, str2, str3, str4); gradient_editor_set_hint (editor, str1, str2, str3, str4);
g_object_unref (color);
g_free (str1); g_free (str1);
g_free (str2); g_free (str2);
g_free (str3); g_free (str3);
@ -1325,11 +1330,11 @@ view_pick_color (GimpGradientEditor *editor,
gint x) gint x)
{ {
GimpDataEditor *data_editor = GIMP_DATA_EDITOR (editor); GimpDataEditor *data_editor = GIMP_DATA_EDITOR (editor);
GeglColor *color = gegl_color_new ("black");
GimpRGB rgb; GimpRGB rgb;
gdouble xpos; gdouble xpos;
gchar *str2; gchar *str2;
gchar *str3; gchar *str3;
GeglColor *color = gegl_color_new ("black");
xpos = control_calc_g_pos (editor, x); xpos = control_calc_g_pos (editor, x);
@ -1337,7 +1342,8 @@ view_pick_color (GimpGradientEditor *editor,
data_editor->context, NULL, data_editor->context, NULL,
xpos, FALSE, FALSE, &rgb); 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)"), str2 = g_strdup_printf (_("RGB (%d, %d, %d)"),
(gint) (rgb.r * 255.0), (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); 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) if (pick_target == GIMP_COLOR_PICK_TARGET_FOREGROUND)
{ {
gimp_context_set_foreground (data_editor->context, color); gimp_context_set_foreground (data_editor->context, color);

View File

@ -671,16 +671,20 @@ gimp_menu_submenu_notify_color (GimpMenuModel *model,
const GParamSpec *pspec, const GParamSpec *pspec,
GtkMenuItem *item) GtkMenuItem *item)
{ {
GimpRGB *color = NULL; GimpRGB *rgb = NULL;
GtkWidget *image = NULL; GtkWidget *image = NULL;
gint width, height; gint width, height;
g_object_get (model, g_object_get (model,
"color", &color, "color", &rgb,
NULL); 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); image = gimp_color_area_new (color, GIMP_COLOR_AREA_SMALL_CHECKS, 0);
gimp_color_area_set_draw_border (GIMP_COLOR_AREA (image), TRUE); 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_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
gtk_widget_set_size_request (image, width, height); gtk_widget_set_size_request (image, width, height);
gtk_widget_show (image); gtk_widget_show (image);
g_object_unref (color);
} }
gimp_menu_item_set_image (item, image, NULL); gimp_menu_item_set_image (item, image, NULL);
g_free (color); g_free (rgb);
} }
static void static void

View File

@ -234,23 +234,13 @@ gimp_cairo_set_source_color (cairo_t *cr,
gboolean softproof, gboolean softproof,
GtkWidget *widget) GtkWidget *widget)
{ {
GimpColorProfile *proof_profile = NULL; const Babl *space;
GimpColorProfile *dest_profile = NULL; gdouble rgba[4];
const Babl *space = NULL;
gdouble rgba[4];
g_return_if_fail (GEGL_IS_COLOR (color)); g_return_if_fail (GEGL_IS_COLOR (color));
g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget)); g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
_gimp_widget_get_profiles (widget, config, space = gimp_widget_get_render_space (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);
gegl_color_get_pixel (color, babl_format_with_space ("R'G'B'A double", space), rgba); 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]); cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]);
} }

View File

@ -39,10 +39,10 @@
/** /**
* SECTION: gimpcolorarea * SECTION: gimpcolorarea
* @title: GimpColorArea * @title: GimpColorArea
* @short_description: Displays a #GimpRGB color, optionally with * @short_description: Displays a [class@Gegl.Color], optionally with
* alpha-channel. * 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; guint rowstride;
GimpColorAreaType type; GimpColorAreaType type;
GimpRGB color; GeglColor *color;
guint draw_border : 1; guint draw_border : 1;
guint needs_render : 1; guint needs_render : 1;
@ -108,7 +108,7 @@ static void gimp_color_area_render_buf (GtkWidget *widget,
guint width, guint width,
guint height, guint height,
guint rowstride, guint rowstride,
GimpRGB *color); GeglColor *color);
static void gimp_color_area_render (GimpColorArea *area); static void gimp_color_area_render (GimpColorArea *area);
static void gimp_color_area_drag_begin (GtkWidget *widget, 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); GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GimpRGB color;
gimp_color_area_signals[COLOR_CHANGED] = gimp_color_area_signals[COLOR_CHANGED] =
g_signal_new ("color-changed", g_signal_new ("color-changed",
@ -172,7 +171,7 @@ gimp_color_area_class_init (GimpColorAreaClass *klass)
klass->color_changed = NULL; klass->color_changed = NULL;
gimp_rgba_set (&color, 0.0, 0.0, 0.0, 1.0); babl_init ();
/** /**
* GimpColorArea:color: * GimpColorArea:color:
@ -182,12 +181,12 @@ gimp_color_area_class_init (GimpColorAreaClass *klass)
* Since: 2.4 * Since: 2.4
*/ */
g_object_class_install_property (object_class, PROP_COLOR, g_object_class_install_property (object_class, PROP_COLOR,
gimp_param_spec_rgb ("color", gegl_param_spec_color_from_string ("color",
"Color", "Color",
"The displayed color", "The displayed color",
TRUE, &color, "black",
GIMP_PARAM_READWRITE | GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT)); G_PARAM_CONSTRUCT));
/** /**
* GimpColorArea:type: * GimpColorArea:type:
* *
@ -246,6 +245,7 @@ gimp_color_area_init (GimpColorArea *area)
priv->height = 0; priv->height = 0;
priv->rowstride = 0; priv->rowstride = 0;
priv->draw_border = FALSE; 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 |
@ -275,6 +275,7 @@ gimp_color_area_finalize (GObject *object)
GimpColorAreaPrivate *priv = GET_PRIVATE (object); GimpColorAreaPrivate *priv = GET_PRIVATE (object);
g_clear_pointer (&priv->buf, g_free); g_clear_pointer (&priv->buf, g_free);
g_clear_object (&priv->color);
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
@ -290,7 +291,7 @@ gimp_color_area_get_property (GObject *object,
switch (property_id) switch (property_id)
{ {
case PROP_COLOR: case PROP_COLOR:
g_value_set_boxed (value, &priv->color); g_value_set_object (value, priv->color);
break; break;
case PROP_TYPE: case PROP_TYPE:
@ -319,7 +320,7 @@ gimp_color_area_set_property (GObject *object,
switch (property_id) switch (property_id)
{ {
case PROP_COLOR: 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; break;
case PROP_TYPE: case PROP_TYPE:
@ -380,6 +381,7 @@ gimp_color_area_draw (GtkWidget *widget,
GimpColorAreaPrivate *priv = GET_PRIVATE (area); GimpColorAreaPrivate *priv = GET_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;
if (! priv->buf) if (! priv->buf)
return FALSE; return FALSE;
@ -458,11 +460,80 @@ gimp_color_area_draw (GtkWidget *widget,
cairo_paint (cr); cairo_paint (cr);
} }
if (priv->config && if (priv->config && ! oog)
((priv->color.r < 0.0 || priv->color.r > 1.0 || {
priv->color.g < 0.0 || priv->color.g > 1.0 || const Babl *format;
priv->color.b < 0.0 || priv->color.b > 1.0) || const Babl *space;
priv->out_of_gamut)) 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; GeglColor *oog_color;
gint side = MIN (priv->width, priv->height) * 2 / 3; gint side = MIN (priv->width, priv->height) * 2 / 3;
@ -500,7 +571,7 @@ gimp_color_area_draw (GtkWidget *widget,
/** /**
* gimp_color_area_new: * 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. * @type: The type of color area to create.
* @drag_mask: The event_mask that should trigger drags. * @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. * Returns: Pointer to the new #GimpColorArea widget.
**/ **/
GtkWidget * GtkWidget *
gimp_color_area_new (const GimpRGB *color, gimp_color_area_new (GeglColor *color,
GimpColorAreaType type, GimpColorAreaType type,
GdkModifierType drag_mask) GdkModifierType drag_mask)
{ {
@ -526,25 +597,27 @@ gimp_color_area_new (const GimpRGB *color,
/** /**
* gimp_color_area_set_color: * gimp_color_area_set_color:
* @area: Pointer to a #GimpColorArea. * @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. * Sets @area to a different @color.
**/ **/
void void
gimp_color_area_set_color (GimpColorArea *area, gimp_color_area_set_color (GimpColorArea *area,
const GimpRGB *color) GeglColor *color)
{ {
GimpColorAreaPrivate *priv; GimpColorAreaPrivate *priv;
g_return_if_fail (GIMP_IS_COLOR_AREA (area)); 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); priv = GET_PRIVATE (area);
if (gimp_rgba_distance (&priv->color, color) < GIMP_RGBA_EPSILON) if (gimp_color_is_perceptually_identical (priv->color, color))
return; return;
priv->color = *color; color = gegl_color_duplicate (color);
g_clear_object (&priv->color);
priv->color = color;
priv->needs_render = TRUE; priv->needs_render = TRUE;
gtk_widget_queue_draw (GTK_WIDGET (area)); gtk_widget_queue_draw (GTK_WIDGET (area));
@ -557,23 +630,22 @@ gimp_color_area_set_color (GimpColorArea *area,
/** /**
* gimp_color_area_get_color: * gimp_color_area_get_color:
* @area: Pointer to a #GimpColorArea. * @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. * Retrieves the current color of the @area.
*
* Returns: (transfer full): a copy of the [class@Gegl.Color] displayed in
* @area.
**/ **/
void GeglColor *
gimp_color_area_get_color (GimpColorArea *area, gimp_color_area_get_color (GimpColorArea *area)
GimpRGB *color)
{ {
GimpColorAreaPrivate *priv; GimpColorAreaPrivate *priv;
g_return_if_fail (GIMP_IS_COLOR_AREA (area)); g_return_val_if_fail (GIMP_IS_COLOR_AREA (area), NULL);
g_return_if_fail (color != NULL);
priv = GET_PRIVATE (area); 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 width,
guint height, guint height,
guint rowstride, guint rowstride,
GimpRGB *color) GeglColor *color)
{ {
guint x, y; GimpColorAreaPrivate *priv = GET_PRIVATE (widget);
guint check_size = 0; const Babl *render_space;
guchar light[3]; guint x, y;
guchar dark[3]; guint check_size = 0;
guchar opaque[3]; guchar light[3];
guchar *p; guchar dark[3];
gdouble frac; gdouble opaque_d[4];
guchar opaque[4];
guchar *p;
gdouble frac;
switch (type) switch (type)
{ {
@ -788,9 +863,11 @@ gimp_color_area_render_buf (GtkWidget *widget,
break; 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++) for (y = 0; y < height; y++)
{ {
@ -811,19 +888,22 @@ gimp_color_area_render_buf (GtkWidget *widget,
} }
light[0] = (GIMP_CHECK_LIGHT + 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 + 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 + 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 + 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 + 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 + 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++) for (y = 0; y < height; y++)
{ {
p = buf + y * rowstride; p = buf + y * rowstride;
@ -901,7 +981,7 @@ gimp_color_area_render (GimpColorArea *area)
priv->type, priv->type,
priv->buf, priv->buf,
priv->width, priv->height, priv->rowstride, priv->width, priv->height, priv->rowstride,
&priv->color); priv->color);
priv->needs_render = FALSE; priv->needs_render = FALSE;
} }
@ -911,7 +991,7 @@ gimp_color_area_drag_begin (GtkWidget *widget,
GdkDragContext *context) GdkDragContext *context)
{ {
GimpColorAreaPrivate *priv = GET_PRIVATE (widget); GimpColorAreaPrivate *priv = GET_PRIVATE (widget);
GimpRGB color; GeglColor *color;
GtkWidget *window; GtkWidget *window;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *color_area; 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_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (window), frame); gtk_container_add (GTK_CONTAINER (window), frame);
gimp_color_area_get_color (GIMP_COLOR_AREA (widget), &color); 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, priv->type, 0); g_object_unref (color);
gtk_widget_set_size_request (color_area, gtk_widget_set_size_request (color_area,
DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE); DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE);
@ -964,7 +1044,8 @@ gimp_color_area_drag_data_received (GtkWidget *widget,
{ {
GimpColorArea *area = GIMP_COLOR_AREA (widget); GimpColorArea *area = GIMP_COLOR_AREA (widget);
const guint16 *vals; const guint16 *vals;
GimpRGB color; GeglColor *color;
GimpRGB rgb;
if (gtk_selection_data_get_length (selection_data) != 8 || if (gtk_selection_data_get_length (selection_data) != 8 ||
gtk_selection_data_get_format (selection_data) != 16) 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); vals = (const guint16 *) gtk_selection_data_get_data (selection_data);
gimp_rgba_set (&color, gimp_rgba_set (&rgb,
(gdouble) vals[0] / 0xffff, (gdouble) vals[0] / 0xffff,
(gdouble) vals[1] / 0xffff, (gdouble) vals[1] / 0xffff,
(gdouble) vals[2] / 0xffff, (gdouble) vals[2] / 0xffff,
(gdouble) vals[3] / 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 static void
@ -992,16 +1077,18 @@ gimp_color_area_drag_data_get (GtkWidget *widget,
guint time) guint time)
{ {
GimpColorAreaPrivate *priv = GET_PRIVATE (widget); GimpColorAreaPrivate *priv = GET_PRIVATE (widget);
gdouble rgb[4];
guint16 vals[4]; guint16 vals[4];
vals[0] = priv->color.r * 0xffff; gegl_color_get_pixel (priv->color, babl_format_with_space ("R'G'B'A double", NULL), rgb);
vals[1] = priv->color.g * 0xffff; vals[0] = rgb[0] * 0xffff;
vals[2] = priv->color.b * 0xffff; vals[1] = rgb[1] * 0xffff;
vals[2] = rgb[2] * 0xffff;
if (priv->type == GIMP_COLOR_AREA_FLAT) if (priv->type == GIMP_COLOR_AREA_FLAT)
vals[3] = 0xffff; vals[3] = 0xffff;
else else
vals[3] = priv->color.a * 0xffff; vals[3] = rgb[3] * 0xffff;
gtk_selection_data_set (selection_data, gtk_selection_data_set (selection_data,
gdk_atom_intern ("application/x-color", FALSE), gdk_atom_intern ("application/x-color", FALSE),

View File

@ -72,14 +72,13 @@ struct _GimpColorAreaClass
GType gimp_color_area_get_type (void) G_GNUC_CONST; 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, GimpColorAreaType type,
GdkModifierType drag_mask); GdkModifierType drag_mask);
void gimp_color_area_set_color (GimpColorArea *area, void gimp_color_area_set_color (GimpColorArea *area,
const GimpRGB *color); GeglColor *color);
void gimp_color_area_get_color (GimpColorArea *area, GeglColor * gimp_color_area_get_color (GimpColorArea *area);
GimpRGB *color);
gboolean gimp_color_area_has_alpha (GimpColorArea *area); gboolean gimp_color_area_has_alpha (GimpColorArea *area);
void gimp_color_area_set_type (GimpColorArea *area, void gimp_color_area_set_type (GimpColorArea *area,

View File

@ -711,16 +711,20 @@ gimp_color_button_get_title (GimpColorButton *button)
**/ **/
void void
gimp_color_button_set_color (GimpColorButton *button, gimp_color_button_set_color (GimpColorButton *button,
const GimpRGB *color) const GimpRGB *rgb)
{ {
GimpColorButtonPrivate *priv; GimpColorButtonPrivate *priv;
GeglColor *color;
g_return_if_fail (GIMP_IS_COLOR_BUTTON (button)); 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); 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); gimp_color_area_set_color (GIMP_COLOR_AREA (priv->color_area), color);
g_object_unref (color);
g_object_notify (G_OBJECT (button), "color"); g_object_notify (G_OBJECT (button), "color");
} }
@ -735,16 +739,19 @@ gimp_color_button_set_color (GimpColorButton *button,
**/ **/
void void
gimp_color_button_get_color (GimpColorButton *button, gimp_color_button_get_color (GimpColorButton *button,
GimpRGB *color) GimpRGB *rgb)
{ {
GimpColorButtonPrivate *priv; GimpColorButtonPrivate *priv;
GeglColor *color;
g_return_if_fail (GIMP_IS_COLOR_BUTTON (button)); 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); 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) 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, g_signal_handlers_block_by_func (priv->color_area,
gimp_color_button_area_changed, gimp_color_button_area_changed,
button); 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, g_signal_handlers_unblock_by_func (priv->color_area,
gimp_color_button_area_changed, gimp_color_button_area_changed,

View File

@ -181,6 +181,7 @@ gimp_color_selection_init (GimpColorSelection *selection)
GtkWidget *button; GtkWidget *button;
GtkSizeGroup *new_group; GtkSizeGroup *new_group;
GtkSizeGroup *old_group; GtkSizeGroup *old_group;
GeglColor *color;
selection->priv = gimp_color_selection_get_instance_private (selection); 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_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (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 ? priv->show_alpha ?
GIMP_COLOR_AREA_SMALL_CHECKS : GIMP_COLOR_AREA_SMALL_CHECKS :
GIMP_COLOR_AREA_FLAT, GIMP_COLOR_AREA_FLAT,
@ -286,7 +289,7 @@ gimp_color_selection_init (GimpColorSelection *selection)
G_CALLBACK (gimp_color_selection_new_color_changed), G_CALLBACK (gimp_color_selection_new_color_changed),
selection); selection);
priv->old_color = gimp_color_area_new (&priv->rgb, priv->old_color = gimp_color_area_new (color,
priv->show_alpha ? priv->show_alpha ?
GIMP_COLOR_AREA_SMALL_CHECKS : GIMP_COLOR_AREA_SMALL_CHECKS :
GIMP_COLOR_AREA_FLAT, GIMP_COLOR_AREA_FLAT,
@ -350,6 +353,8 @@ gimp_color_selection_init (GimpColorSelection *selection)
g_signal_connect (entry, "color-changed", g_signal_connect (entry, "color-changed",
G_CALLBACK (gimp_color_selection_entry_changed), G_CALLBACK (gimp_color_selection_entry_changed),
selection); selection);
g_object_unref (color);
} }
static void static void
@ -492,16 +497,20 @@ gimp_color_selection_get_color (GimpColorSelection *selection,
**/ **/
void void
gimp_color_selection_set_old_color (GimpColorSelection *selection, gimp_color_selection_set_old_color (GimpColorSelection *selection,
const GimpRGB *color) const GimpRGB *rgb)
{ {
GimpColorSelectionPrivate *priv; GimpColorSelectionPrivate *priv;
GeglColor *color;
g_return_if_fail (GIMP_IS_COLOR_SELECTION (selection)); 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); 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); 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 void
gimp_color_selection_get_old_color (GimpColorSelection *selection, gimp_color_selection_get_old_color (GimpColorSelection *selection,
GimpRGB *color) GimpRGB *rgb)
{ {
GimpColorSelectionPrivate *priv; GimpColorSelectionPrivate *priv;
GeglColor *color;
g_return_if_fail (GIMP_IS_COLOR_SELECTION (selection)); 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); 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) gimp_color_selection_reset (GimpColorSelection *selection)
{ {
GimpColorSelectionPrivate *priv; GimpColorSelectionPrivate *priv;
GimpRGB color; GeglColor *color;
GimpRGB rgb;
g_return_if_fail (GIMP_IS_COLOR_SELECTION (selection)); g_return_if_fail (GIMP_IS_COLOR_SELECTION (selection));
priv = GET_PRIVATE (selection); 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));
gimp_color_selection_set_color (selection, &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) GimpColorSelection *selection)
{ {
GimpColorSelectionPrivate *priv = GET_PRIVATE (selection); GimpColorSelectionPrivate *priv = GET_PRIVATE (selection);
GeglColor *color;
gimp_color_area_get_color (GIMP_COLOR_AREA (widget), &priv->rgb); color = gimp_color_area_get_color (GIMP_COLOR_AREA (widget));
gimp_rgb_to_hsv (&priv->rgb, &priv->hsv); 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, gimp_color_selection_update (selection,
UPDATE_NOTEBOOK | UPDATE_SCALES | UPDATE_ENTRY); UPDATE_NOTEBOOK | UPDATE_SCALES | UPDATE_ENTRY);
gimp_color_selection_color_changed (selection); gimp_color_selection_color_changed (selection);
g_object_unref (color);
} }
static void static void
@ -809,15 +829,20 @@ gimp_color_selection_update (GimpColorSelection *selection,
if (update & UPDATE_COLOR) if (update & UPDATE_COLOR)
{ {
GeglColor *color;
g_signal_handlers_block_by_func (priv->new_color, g_signal_handlers_block_by_func (priv->new_color,
gimp_color_selection_new_color_changed, gimp_color_selection_new_color_changed,
selection); selection);
gimp_color_area_set_color (GIMP_COLOR_AREA (priv->new_color), color = gegl_color_new (NULL);
&priv->rgb); 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, g_signal_handlers_unblock_by_func (priv->new_color,
gimp_color_selection_new_color_changed, gimp_color_selection_new_color_changed,
selection); selection);
g_object_unref (color);
} }
} }

View File

@ -148,18 +148,19 @@ gimp_label_color_class_init (GimpLabelColorClass *klass)
static void static void
gimp_label_color_init (GimpLabelColor *color) gimp_label_color_init (GimpLabelColor *color)
{ {
GimpLabelColorPrivate *priv = gimp_label_color_get_instance_private (color); GimpLabelColorPrivate *priv = gimp_label_color_get_instance_private (color);
GimpRGB black; GeglColor *black = gegl_color_new ("black");
gimp_rgba_set (&black, 0.0, 0.0, 0.0, 1.0);
priv->editable = FALSE; 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); GDK_BUTTON1_MASK | GDK_BUTTON2_MASK);
/* Typically for a labelled color area, a small square next to your /* Typically for a labelled color area, a small square next to your
* label is probably what you want to display. * label is probably what you want to display.
*/ */
gtk_widget_set_size_request (priv->area, 20, 20); gtk_widget_set_size_request (priv->area, 20, 20);
g_object_unref (black);
} }
static void static void
@ -224,7 +225,7 @@ gimp_label_color_set_property (GObject *object,
{ {
const gchar *dialog_title; const gchar *dialog_title;
GimpLabeled *labeled; GimpLabeled *labeled;
GimpRGB *rgb; GeglColor *color;
GimpColorAreaType type; GimpColorAreaType type;
gboolean attached; gboolean attached;
@ -238,18 +239,20 @@ gimp_label_color_set_property (GObject *object,
attached = (gtk_widget_get_parent (priv->area) != NULL); attached = (gtk_widget_get_parent (priv->area) != NULL);
g_object_get (priv->area, g_object_get (priv->area,
"type", &type, "type", &type,
"color", &rgb, "color", &color,
NULL); NULL);
gtk_widget_destroy (priv->area); gtk_widget_destroy (priv->area);
priv->editable = g_value_get_boolean (value); priv->editable = g_value_get_boolean (value);
if (priv->editable) if (priv->editable)
priv->area = gimp_color_button_new (dialog_title, priv->area = gimp_color_button_new (dialog_title,
20, 20, rgb, type); 20, 20, color, type);
else else
priv->area = gimp_color_area_new (rgb, type, priv->area = gimp_color_area_new (color, type,
GDK_BUTTON1_MASK | GDK_BUTTON2_MASK); GDK_BUTTON1_MASK | GDK_BUTTON2_MASK);
g_object_unref (color);
gtk_widget_set_size_request (priv->area, 20, 20); gtk_widget_set_size_request (priv->area, 20, 20);
g_object_bind_property_full (G_OBJECT (priv->area), "color", g_object_bind_property_full (G_OBJECT (priv->area), "color",

View File

@ -4090,8 +4090,7 @@ gimp_prop_color_area_new (GObject *config,
{ {
GParamSpec *param_spec; GParamSpec *param_spec;
GtkWidget *area; GtkWidget *area;
GeglColor *value = NULL; GeglColor *color = NULL;
GimpRGB rgb = { 0 };
param_spec = check_param_spec_w (config, property_name, param_spec = check_param_spec_w (config, property_name,
GEGL_TYPE_PARAM_COLOR, G_STRFUNC); GEGL_TYPE_PARAM_COLOR, G_STRFUNC);
@ -4099,16 +4098,13 @@ gimp_prop_color_area_new (GObject *config,
return NULL; return NULL;
g_object_get (config, g_object_get (config,
property_name, &value, property_name, &color,
NULL); NULL);
if (value != NULL) area = gimp_color_area_new (color, type, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK);
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);
gtk_widget_set_size_request (area, width, height); 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); set_param_spec (G_OBJECT (area), area, param_spec);
@ -4133,15 +4129,12 @@ gimp_prop_color_area_callback (GtkWidget *area,
{ {
GParamSpec *param_spec; GParamSpec *param_spec;
GeglColor *color; GeglColor *color;
GimpRGB value;
param_spec = get_param_spec (G_OBJECT (area)); param_spec = get_param_spec (G_OBJECT (area));
if (! param_spec) if (! param_spec)
return; return;
color = gegl_color_new (NULL); color = gimp_color_area_get_color (GIMP_COLOR_AREA (area));
gimp_color_area_get_color (GIMP_COLOR_AREA (area), &value);
gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), &value);
g_signal_handlers_block_by_func (config, g_signal_handlers_block_by_func (config,
gimp_prop_color_area_notify, gimp_prop_color_area_notify,
@ -4163,7 +4156,6 @@ gimp_prop_color_area_notify (GObject *config,
GtkWidget *area) GtkWidget *area)
{ {
GeglColor *color = NULL; GeglColor *color = NULL;
GimpRGB value;
g_object_get (config, g_object_get (config,
param_spec->name, &color, param_spec->name, &color,
@ -4173,8 +4165,7 @@ gimp_prop_color_area_notify (GObject *config,
gimp_prop_color_area_callback, gimp_prop_color_area_callback,
config); config);
gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &value); gimp_color_area_set_color (GIMP_COLOR_AREA (area), color);
gimp_color_area_set_color (GIMP_COLOR_AREA (area), &value);
g_clear_object (&color); g_clear_object (&color);

View File

@ -498,6 +498,7 @@ EXPORTS
gimp_widget_get_color_profile gimp_widget_get_color_profile
gimp_widget_get_color_transform gimp_widget_get_color_transform
gimp_widget_get_monitor gimp_widget_get_monitor
gimp_widget_get_render_space
gimp_widget_set_bound_property gimp_widget_set_bound_property
gimp_widget_set_identifier gimp_widget_set_identifier
gimp_widget_set_native_handle gimp_widget_set_native_handle

View File

@ -1055,6 +1055,47 @@ gimp_widget_get_color_transform (GtkWidget *widget,
return NULL; 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: * gimp_widget_set_native_handle:
* @widget: a #GtkWindow * @widget: a #GtkWindow

View File

@ -64,17 +64,19 @@ GimpColorTransform * gimp_widget_get_color_transform (GtkWidget *widget,
GimpColorProfile *softproof_profile, GimpColorProfile *softproof_profile,
GimpColorRenderingIntent proof_intent, GimpColorRenderingIntent proof_intent,
gboolean proof_bpc); gboolean proof_bpc);
const Babl * gimp_widget_get_render_space (GtkWidget *widget,
GimpColorConfig *config);
void gimp_widget_set_native_handle (GtkWidget *widget, void gimp_widget_set_native_handle (GtkWidget *widget,
GBytes **handle); GBytes **handle);
/* Internal use */ /* Internal use */
G_GNUC_INTERNAL void _gimp_widget_get_profiles (GtkWidget *widget, G_GNUC_INTERNAL void _gimp_widget_get_profiles (GtkWidget *widget,
GimpColorConfig *config, GimpColorConfig *config,
GimpColorProfile **proof_profile, GimpColorProfile **proof_profile,
GimpColorProfile **dest_profile); GimpColorProfile **dest_profile);
G_END_DECLS G_END_DECLS

View File

@ -2020,6 +2020,7 @@ color_map_create (const gchar *name,
GtkWidget *frame; GtkWidget *frame;
GtkWidget *arrow; GtkWidget *arrow;
ColorMap *color_map = g_new (ColorMap, 1); ColorMap *color_map = g_new (ColorMap, 1);
GeglColor *color;
gimp_rgb_set_alpha (data, 1.0); gimp_rgb_set_alpha (data, 1.0);
color_map->color = data; 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_box_pack_start (GTK_BOX (color_map->hbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame); gtk_widget_show (frame);
color_map->orig_preview = color = gegl_color_new (NULL);
gimp_color_area_new (fixed_point ? data : orig_color, gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), fixed_point ? data : orig_color);
GIMP_COLOR_AREA_FLAT, 0); 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_drag_dest_unset (color_map->orig_preview);
gtk_widget_set_size_request (color_map->orig_preview, gtk_widget_set_size_request (color_map->orig_preview,
COLOR_SAMPLE_SIZE, COLOR_SAMPLE_SIZE); COLOR_SAMPLE_SIZE, COLOR_SAMPLE_SIZE);
@ -2091,8 +2093,14 @@ color_map_update (ColorMap *color_map)
color_map->color); color_map->color);
if (color_map->fixed_point) 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 static void