From bab9ed18c444bca5452196ca9d890e7479352bf9 Mon Sep 17 00:00:00 2001 From: Jehan Date: Sun, 24 Dec 2023 20:27:23 +0900 Subject: [PATCH] app: color drag'n drop is now space-invaded. We can now drop any color model and encoding with any space. The exact color information is passed with. --- app/display/gimpdisplayshell-dnd.c | 7 +- app/widgets/gimpcontainertreeview-dnd.c | 8 +- app/widgets/gimpcontainertreeview.h | 2 +- app/widgets/gimpdnd.c | 31 +++--- app/widgets/gimpdnd.h | 4 +- app/widgets/gimpdrawabletreeview.c | 88 ++++++++--------- app/widgets/gimpfgbgeditor.c | 31 +++--- app/widgets/gimpgradienteditor.c | 32 ++++--- app/widgets/gimplayertreeview.c | 4 +- app/widgets/gimppaletteeditor.c | 22 ++--- app/widgets/gimppaletteview.c | 26 ++--- app/widgets/gimppaletteview.h | 2 +- app/widgets/gimpselectiondata.c | 122 +++++++++++++++++++----- app/widgets/gimpselectiondata.h | 5 +- app/widgets/gimpselectioneditor.c | 17 ++-- 15 files changed, 222 insertions(+), 179 deletions(-) diff --git a/app/display/gimpdisplayshell-dnd.c b/app/display/gimpdisplayshell-dnd.c index d7aad98815..bc294ba2ac 100644 --- a/app/display/gimpdisplayshell-dnd.c +++ b/app/display/gimpdisplayshell-dnd.c @@ -86,7 +86,7 @@ static void gimp_display_shell_drop_pattern (GtkWidget *widget, static void gimp_display_shell_drop_color (GtkWidget *widget, gint x, gint y, - const GimpRGB *color, + GeglColor *color, gpointer data); static void gimp_display_shell_drop_buffer (GtkWidget *widget, gint x, @@ -436,25 +436,22 @@ static void gimp_display_shell_drop_color (GtkWidget *widget, gint x, gint y, - const GimpRGB *rgb, + GeglColor *color, gpointer data) { GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data); GimpFillOptions *options = gimp_fill_options_new (shell->display->gimp, NULL, FALSE); - GeglColor *color = gegl_color_new ("black"); GIMP_LOG (DND, NULL); gimp_fill_options_set_style (options, GIMP_FILL_STYLE_FG_COLOR); - gegl_color_set_rgba_with_space (color, rgb->r, rgb->g, rgb->b, rgb->a, NULL); gimp_context_set_foreground (GIMP_CONTEXT (options), color); gimp_display_shell_dnd_fill (shell, options, C_("undo-type", "Drop color to layer")); g_object_unref (options); - g_object_unref (color); } static void diff --git a/app/widgets/gimpcontainertreeview-dnd.c b/app/widgets/gimpcontainertreeview-dnd.c index 35c86f0b62..e09ff08c9a 100644 --- a/app/widgets/gimpcontainertreeview-dnd.c +++ b/app/widgets/gimpcontainertreeview-dnd.c @@ -603,14 +603,14 @@ gimp_container_tree_view_drag_data_received (GtkWidget *widget, case GIMP_DND_TYPE_COLOR: if (tree_view_class->drop_color) { - GimpRGB color; + GeglColor *color; - if (gimp_selection_data_get_color (selection_data, &color)) + if ((color = gimp_selection_data_get_color (selection_data))) { - tree_view_class->drop_color (tree_view, &color, - dest_viewable, drop_pos); + tree_view_class->drop_color (tree_view, color, dest_viewable, drop_pos); success = TRUE; + g_object_unref (color); } } break; diff --git a/app/widgets/gimpcontainertreeview.h b/app/widgets/gimpcontainertreeview.h index ea96e206db..1473705a39 100644 --- a/app/widgets/gimpcontainertreeview.h +++ b/app/widgets/gimpcontainertreeview.h @@ -77,7 +77,7 @@ struct _GimpContainerTreeViewClass GimpViewable *dest_viewable, GtkTreeViewDropPosition drop_pos); void (* drop_color) (GimpContainerTreeView *tree_view, - const GimpRGB *src_color, + GeglColor *src_color, GimpViewable *dest_viewable, GtkTreeViewDropPosition drop_pos); void (* drop_uri_list) (GimpContainerTreeView *tree_view, diff --git a/app/widgets/gimpdnd.c b/app/widgets/gimpdnd.c index 7b769096f1..72de4abb9b 100644 --- a/app/widgets/gimpdnd.c +++ b/app/widgets/gimpdnd.c @@ -1387,27 +1387,22 @@ gimp_dnd_get_color_icon (GtkWidget *widget, gpointer get_color_data) { GtkWidget *color_area; - GeglColor *color; - GimpRGB rgb; + GeglColor *color = NULL; - (* (GimpDndDragColorFunc) get_color_func) (widget, &rgb, get_color_data); + (* (GimpDndDragColorFunc) get_color_func) (widget, &color, get_color_data); GIMP_LOG (DND, "called"); g_object_set_data_full (G_OBJECT (context), - "gimp-dnd-color", g_memdup2 (&rgb, sizeof (GimpRGB)), - (GDestroyNotify) g_free); + "gimp-dnd-color", color, + (GDestroyNotify) g_object_unref); - 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; } @@ -1418,19 +1413,19 @@ gimp_dnd_get_color_data (GtkWidget *widget, gpointer get_color_data, GtkSelectionData *selection) { - GimpRGB *c; - GimpRGB color; + GeglColor *color = NULL; - c = g_object_get_data (G_OBJECT (context), "gimp-dnd-color"); + color = g_object_get_data (G_OBJECT (context), "gimp-dnd-color"); - if (c) - color = *c; + if (color) + color = g_object_ref (color); else (* (GimpDndDragColorFunc) get_color_func) (widget, &color, get_color_data); GIMP_LOG (DND, "called"); - gimp_selection_data_set_color (selection, &color); + gimp_selection_data_set_color (selection, color); + g_object_unref (color); } static gboolean @@ -1441,14 +1436,14 @@ gimp_dnd_set_color_data (GtkWidget *widget, gpointer set_color_data, GtkSelectionData *selection) { - GimpRGB color; + GeglColor *color; GIMP_LOG (DND, "called"); - if (! gimp_selection_data_get_color (selection, &color)) + if (! (color = gimp_selection_data_get_color (selection))) return FALSE; - (* (GimpDndDropColorFunc) set_color_func) (widget, x, y, &color, + (* (GimpDndDropColorFunc) set_color_func) (widget, x, y, color, set_color_data); return TRUE; diff --git a/app/widgets/gimpdnd.h b/app/widgets/gimpdnd.h index 52f2c774b9..dca460cd61 100644 --- a/app/widgets/gimpdnd.h +++ b/app/widgets/gimpdnd.h @@ -132,12 +132,12 @@ void gimp_dnd_uri_list_dest_remove (GtkWidget *widget); /* color dnd functions */ typedef void (* GimpDndDragColorFunc) (GtkWidget *widget, - GimpRGB *color, + GeglColor **color, gpointer data); typedef void (* GimpDndDropColorFunc) (GtkWidget *widget, gint x, gint y, - const GimpRGB *color, + GeglColor *color, gpointer data); void gimp_dnd_color_source_add (GtkWidget *widget, diff --git a/app/widgets/gimpdrawabletreeview.c b/app/widgets/gimpdrawabletreeview.c index a895688c05..d76bf03197 100644 --- a/app/widgets/gimpdrawabletreeview.c +++ b/app/widgets/gimpdrawabletreeview.c @@ -45,48 +45,48 @@ static void gimp_drawable_tree_view_view_iface_init (GimpContainerViewInterface *iface); -static void gimp_drawable_tree_view_constructed (GObject *object); +static void gimp_drawable_tree_view_constructed (GObject *object); -static gboolean gimp_drawable_tree_view_select_items (GimpContainerView *view, - GList *items, - GList *paths); +static gboolean gimp_drawable_tree_view_select_items (GimpContainerView *view, + GList *items, + GList *paths); -static gboolean gimp_drawable_tree_view_drop_possible(GimpContainerTreeView *view, - GimpDndType src_type, - GList *src_viewables, - GimpViewable *dest_viewable, - GtkTreePath *drop_path, - GtkTreeViewDropPosition drop_pos, - GtkTreeViewDropPosition *return_drop_pos, - GdkDragAction *return_drag_action); -static void gimp_drawable_tree_view_drop_viewables (GimpContainerTreeView *view, - GList *src_viewables, - GimpViewable *dest_viewable, - GtkTreeViewDropPosition drop_pos); -static void gimp_drawable_tree_view_drop_color (GimpContainerTreeView *view, - const GimpRGB *color, - GimpViewable *dest_viewable, - GtkTreeViewDropPosition drop_pos); +static gboolean gimp_drawable_tree_view_drop_possible (GimpContainerTreeView *view, + GimpDndType src_type, + GList *src_viewables, + GimpViewable *dest_viewable, + GtkTreePath *drop_path, + GtkTreeViewDropPosition drop_pos, + GtkTreeViewDropPosition *return_drop_pos, + GdkDragAction *return_drag_action); +static void gimp_drawable_tree_view_drop_viewables (GimpContainerTreeView *view, + GList *src_viewables, + GimpViewable *dest_viewable, + GtkTreeViewDropPosition drop_pos); +static void gimp_drawable_tree_view_drop_color (GimpContainerTreeView *view, + GeglColor *color, + GimpViewable *dest_viewable, + GtkTreeViewDropPosition drop_pos); -static void gimp_drawable_tree_view_set_image (GimpItemTreeView *view, - GimpImage *image); +static void gimp_drawable_tree_view_set_image (GimpItemTreeView *view, + GimpImage *image); static void gimp_drawable_tree_view_floating_selection_changed - (GimpImage *image, - GimpDrawableTreeView *view); + (GimpImage *image, + GimpDrawableTreeView *view); static void gimp_drawable_tree_view_new_pattern_dropped - (GtkWidget *widget, - gint x, - gint y, - GimpViewable *viewable, - gpointer data); + (GtkWidget *widget, + gint x, + gint y, + GimpViewable *viewable, + gpointer data); static void gimp_drawable_tree_view_new_color_dropped - (GtkWidget *widget, - gint x, - gint y, - const GimpRGB *color, - gpointer data); + (GtkWidget *widget, + gint x, + gint y, + GeglColor *color, + gpointer data); G_DEFINE_TYPE_WITH_CODE (GimpDrawableTreeView, gimp_drawable_tree_view, @@ -281,7 +281,7 @@ gimp_drawable_tree_view_drop_viewables (GimpContainerTreeView *view, static void gimp_drawable_tree_view_drop_color (GimpContainerTreeView *view, - const GimpRGB *rgb, + GeglColor *color, GimpViewable *dest_viewable, GtkTreeViewDropPosition drop_pos) { @@ -289,9 +289,6 @@ gimp_drawable_tree_view_drop_color (GimpContainerTreeView *view, { GimpImage *image = gimp_item_get_image (GIMP_ITEM (dest_viewable)); GimpFillOptions *options = gimp_fill_options_new (image->gimp, NULL, FALSE); - GeglColor *color = gegl_color_new ("black"); - - gegl_color_set_rgba_with_space (color, rgb->r, rgb->g, rgb->b, rgb->a, NULL); gimp_fill_options_set_style (options, GIMP_FILL_STYLE_FG_COLOR); gimp_context_set_foreground (GIMP_CONTEXT (options), color); @@ -301,7 +298,6 @@ gimp_drawable_tree_view_drop_color (GimpContainerTreeView *view, C_("undo-type", "Drop color to layer")); g_object_unref (options); - g_object_unref (color); gimp_image_flush (image); } @@ -388,18 +384,15 @@ gimp_drawable_tree_view_new_pattern_dropped (GtkWidget *widget, } static void -gimp_drawable_tree_view_new_color_dropped (GtkWidget *widget, - gint x, - gint y, - const GimpRGB *rgb, - gpointer data) +gimp_drawable_tree_view_new_color_dropped (GtkWidget *widget, + gint x, + gint y, + GeglColor *color, + gpointer data) { GimpItemTreeView *view = GIMP_ITEM_TREE_VIEW (data); GimpImage *image = gimp_item_tree_view_get_image (view); GimpFillOptions *options = gimp_fill_options_new (image->gimp, NULL, FALSE); - GeglColor *color = gegl_color_new ("black"); - - gegl_color_set_rgba_with_space (color, rgb->r, rgb->g, rgb->b, rgb->a, NULL); gimp_fill_options_set_style (options, GIMP_FILL_STYLE_FG_COLOR); gimp_context_set_foreground (GIMP_CONTEXT (options), color); @@ -408,5 +401,4 @@ gimp_drawable_tree_view_new_color_dropped (GtkWidget *widget, C_("undo-type", "Drop color to layer")); g_object_unref (options); - g_object_unref (color); } diff --git a/app/widgets/gimpfgbgeditor.c b/app/widgets/gimpfgbgeditor.c index fe421725d0..60d8530c0e 100644 --- a/app/widgets/gimpfgbgeditor.c +++ b/app/widgets/gimpfgbgeditor.c @@ -104,12 +104,12 @@ static gboolean gimp_fg_bg_editor_query_tooltip (GtkWidget *widget, GtkTooltip *tooltip); static void gimp_fg_bg_editor_drag_color (GtkWidget *widget, - GimpRGB *color, + GeglColor **color, gpointer data); static void gimp_fg_bg_editor_drop_color (GtkWidget *widget, gint x, gint y, - const GimpRGB *color, + GeglColor *color, gpointer data); static void gimp_fg_bg_editor_image_changed (GimpFgBgEditor *editor, @@ -722,42 +722,35 @@ gimp_fg_bg_editor_set_active (GimpFgBgEditor *editor, /* private functions */ static void -gimp_fg_bg_editor_drag_color (GtkWidget *widget, - GimpRGB *rgb, +gimp_fg_bg_editor_drag_color (GtkWidget *widget, + GeglColor **color, gpointer data) { GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (widget); - GeglColor *color = NULL; if (editor->context) { switch (editor->active_color) { case GIMP_ACTIVE_COLOR_FOREGROUND: - color = gimp_context_get_foreground (editor->context); + *color = gegl_color_duplicate (gimp_context_get_foreground (editor->context)); break; case GIMP_ACTIVE_COLOR_BACKGROUND: - color = gimp_context_get_background (editor->context); + *color = gegl_color_duplicate (gimp_context_get_background (editor->context)); break; } } - - if (color != NULL) - gegl_color_get_rgba_with_space (color, &rgb->r, &rgb->g, &rgb->b, &rgb->a, NULL); } static void -gimp_fg_bg_editor_drop_color (GtkWidget *widget, - gint x, - gint y, - const GimpRGB *rgb, - gpointer data) +gimp_fg_bg_editor_drop_color (GtkWidget *widget, + gint x, + gint y, + GeglColor *color, + gpointer data) { GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (widget); - GeglColor *color = gegl_color_new ("black"); - - gegl_color_set_rgba_with_space (color, rgb->r, rgb->g, rgb->b, rgb->a, NULL); if (editor->context) { @@ -779,8 +772,6 @@ gimp_fg_bg_editor_drop_color (GtkWidget *widget, break; } } - - g_object_unref (color); } static void diff --git a/app/widgets/gimpgradienteditor.c b/app/widgets/gimpgradienteditor.c index 023a73310b..cf154e541b 100644 --- a/app/widgets/gimpgradienteditor.c +++ b/app/widgets/gimpgradienteditor.c @@ -135,12 +135,12 @@ static void gradient_editor_drop_gradient (GtkWidget *widget, static void gradient_editor_drop_color (GtkWidget *widget, gint x, gint y, - const GimpRGB *color, + GeglColor *color, gpointer data); static void gradient_editor_control_drop_color (GtkWidget *widget, gint x, gint y, - const GimpRGB *color, + GeglColor *color, gpointer data); static void gradient_editor_scrollbar_update (GtkAdjustment *adj, GimpGradientEditor *editor); @@ -848,7 +848,7 @@ static void gradient_editor_drop_color (GtkWidget *widget, gint x, gint y, - const GimpRGB *rgb, + GeglColor *color, gpointer data) { GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data); @@ -873,25 +873,27 @@ gradient_editor_drop_color (GtkWidget *widget, { lseg->right = xpos; lseg->middle = (lseg->left + lseg->right) / 2.0; - gegl_color_set_pixel (lseg->right_color, babl_format ("R'G'B'A double"), rgb); + g_clear_object (&lseg->right_color); + lseg->right_color = gegl_color_duplicate (color); } if (rseg) { rseg->left = xpos; rseg->middle = (rseg->left + rseg->right) / 2.0; - gegl_color_set_pixel (rseg->left_color, babl_format ("R'G'B'A double"), rgb); + g_clear_object (&rseg->left_color); + rseg->left_color = gegl_color_duplicate (color); } gimp_data_thaw (GIMP_DATA (gradient)); } static void -gradient_editor_control_drop_color (GtkWidget *widget, - gint x, - gint y, - const GimpRGB *rgb, - gpointer data) +gradient_editor_control_drop_color (GtkWidget *widget, + gint x, + gint y, + GeglColor *color, + gpointer data) { GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data); GimpGradient *gradient; @@ -923,10 +925,16 @@ gradient_editor_control_drop_color (GtkWidget *widget, gimp_data_freeze (GIMP_DATA (gradient)); if (lseg) - gegl_color_set_pixel (lseg->right_color, babl_format ("R'G'B'A double"), rgb); + { + g_clear_object (&lseg->right_color); + lseg->right_color = gegl_color_duplicate (color); + } if (rseg) - gegl_color_set_pixel (rseg->left_color, babl_format ("R'G'B'A double"), rgb); + { + g_clear_object (&rseg->left_color); + rseg->left_color = gegl_color_duplicate (color); + } gimp_data_thaw (GIMP_DATA (gradient)); } diff --git a/app/widgets/gimplayertreeview.c b/app/widgets/gimplayertreeview.c index 8a0d2a2180..0da23d43e4 100644 --- a/app/widgets/gimplayertreeview.c +++ b/app/widgets/gimplayertreeview.c @@ -118,7 +118,7 @@ static gboolean gimp_layer_tree_view_drop_possible (GimpContainer GtkTreeViewDropPosition *return_drop_pos, GdkDragAction *return_drag_action); static void gimp_layer_tree_view_drop_color (GimpContainerTreeView *view, - const GimpRGB *color, + GeglColor *color, GimpViewable *dest_viewable, GtkTreeViewDropPosition drop_pos); static void gimp_layer_tree_view_drop_uri_list (GimpContainerTreeView *view, @@ -743,7 +743,7 @@ gimp_layer_tree_view_drop_possible (GimpContainerTreeView *tree_view, static void gimp_layer_tree_view_drop_color (GimpContainerTreeView *view, - const GimpRGB *color, + GeglColor *color, GimpViewable *dest_viewable, GtkTreeViewDropPosition drop_pos) { diff --git a/app/widgets/gimppaletteeditor.c b/app/widgets/gimppaletteeditor.c index 14855a7cf9..36c489a3cb 100644 --- a/app/widgets/gimppaletteeditor.c +++ b/app/widgets/gimppaletteeditor.c @@ -93,7 +93,7 @@ static void palette_editor_drop_palette (GtkWidget *widget, static void palette_editor_drop_color (GtkWidget *widget, gint x, gint y, - const GimpRGB *color, + GeglColor *color, gpointer data); static void palette_editor_entry_clicked (GimpPaletteView *view, @@ -113,7 +113,7 @@ static gboolean palette_editor_popup_menu (GtkWidget *widget, gpointer user_data); static void palette_editor_color_dropped (GimpPaletteView *view, GimpPaletteEntry *entry, - const GimpRGB *color, + GeglColor *color, GimpPaletteEditor *editor); static void palette_editor_color_name_changed (GtkWidget *widget, @@ -749,11 +749,11 @@ palette_editor_drop_palette (GtkWidget *widget, } static void -palette_editor_drop_color (GtkWidget *widget, - gint x, - gint y, - const GimpRGB *rgb, - gpointer data) +palette_editor_drop_color (GtkWidget *widget, + gint x, + gint y, + GeglColor *color, + gpointer data) { GimpPaletteEditor *editor = data; @@ -761,12 +761,9 @@ palette_editor_drop_color (GtkWidget *widget, { GimpPalette *palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); GimpPaletteEntry *entry; - GeglColor *color = gegl_color_new (NULL); - gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), rgb); entry = gimp_palette_add_entry (palette, -1, NULL, color); gimp_palette_view_select_entry (GIMP_PALETTE_VIEW (editor->view), entry); - g_object_unref (color); } } @@ -888,22 +885,19 @@ palette_editor_popup_menu (GtkWidget *widget, static void palette_editor_color_dropped (GimpPaletteView *view, GimpPaletteEntry *entry, - const GimpRGB *rgb, + GeglColor *color, GimpPaletteEditor *editor) { if (GIMP_DATA_EDITOR (editor)->data_editable) { GimpPalette *palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); - GeglColor *color = gegl_color_new (NULL); gint pos = -1; if (entry) pos = gimp_palette_get_entry_position (palette, entry); - gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), rgb); entry = gimp_palette_add_entry (palette, pos, NULL, color); gimp_palette_view_select_entry (GIMP_PALETTE_VIEW (editor->view), entry); - g_object_unref (color); } } diff --git a/app/widgets/gimppaletteview.c b/app/widgets/gimppaletteview.c index f348a816eb..a1d8f28708 100644 --- a/app/widgets/gimppaletteview.c +++ b/app/widgets/gimppaletteview.c @@ -67,12 +67,12 @@ static void gimp_palette_view_expose_entry (GimpPaletteView *view, static void gimp_palette_view_invalidate (GimpPalette *palette, GimpPaletteView *view); static void gimp_palette_view_drag_color (GtkWidget *widget, - GimpRGB *color, + GeglColor **color, gpointer data); static void gimp_palette_view_drop_color (GtkWidget *widget, gint x, gint y, - const GimpRGB *color, + GeglColor *color, gpointer data); @@ -127,7 +127,7 @@ gimp_palette_view_class_init (GimpPaletteViewClass *klass) gimp_marshal_VOID__POINTER_BOXED, G_TYPE_NONE, 2, G_TYPE_POINTER, - GIMP_TYPE_RGB); + GEGL_TYPE_COLOR); widget_class->draw = gimp_palette_view_draw; widget_class->button_press_event = gimp_palette_view_button_press; @@ -512,24 +512,24 @@ gimp_palette_view_invalidate (GimpPalette *palette, } static void -gimp_palette_view_drag_color (GtkWidget *widget, - GimpRGB *rgb, - gpointer data) +gimp_palette_view_drag_color (GtkWidget *widget, + GeglColor **color, + gpointer data) { GimpPaletteView *view = GIMP_PALETTE_VIEW (data); if (view->dnd_entry) - gegl_color_get_pixel (view->dnd_entry->color, babl_format ("R'G'B'A double"), rgb); + *color = gegl_color_duplicate (view->dnd_entry->color); else - gimp_rgba_set (rgb, 0.0, 0.0, 0.0, 1.0); + *color = gegl_color_new ("black"); } static void -gimp_palette_view_drop_color (GtkWidget *widget, - gint x, - gint y, - const GimpRGB *color, - gpointer data) +gimp_palette_view_drop_color (GtkWidget *widget, + gint x, + gint y, + GeglColor *color, + gpointer data) { GimpPaletteView *view = GIMP_PALETTE_VIEW (data); GimpPaletteEntry *entry; diff --git a/app/widgets/gimppaletteview.h b/app/widgets/gimppaletteview.h index 9c215e43e5..cb94fd8de0 100644 --- a/app/widgets/gimppaletteview.h +++ b/app/widgets/gimppaletteview.h @@ -57,7 +57,7 @@ struct _GimpPaletteViewClass GimpPaletteEntry *entry); void (* color_dropped) (GimpPaletteView *view, GimpPaletteEntry *entry, - const GimpRGB *color); + GeglColor *color); }; diff --git a/app/widgets/gimpselectiondata.c b/app/widgets/gimpselectiondata.c index 7bbd7d28ea..dea192f2e6 100644 --- a/app/widgets/gimpselectiondata.c +++ b/app/widgets/gimpselectiondata.c @@ -280,51 +280,123 @@ gimp_selection_data_get_uri_list (GtkSelectionData *selection) void gimp_selection_data_set_color (GtkSelectionData *selection, - const GimpRGB *color) + GeglColor *color) { - guint16 vals[4]; - guchar r, g, b, a; + const Babl *format; + const gchar *encoding; + gint encoding_length; + guchar pixel[40]; + gint pixel_length; + guint8 *profile_data = NULL; + int profile_length = 0; + guchar *data; + gint data_length; g_return_if_fail (selection != NULL); g_return_if_fail (color != NULL); - gimp_rgba_get_uchar (color, &r, &g, &b, &a); + format = gegl_color_get_format (color); + encoding = babl_format_get_encoding (format); + encoding_length = strlen (encoding) + 1; + pixel_length = babl_format_get_bytes_per_pixel (format); + gegl_color_get_pixel (color, format, pixel); - vals[0] = r + (r << 8); - vals[1] = g + (g << 8); - vals[2] = b + (b << 8); - vals[3] = a + (a << 8); + if (babl_format_get_space (format) != babl_space ("sRGB")) + profile_data = (guint8 *) babl_space_get_icc (babl_format_get_space (format), + &profile_length); + + data_length = encoding_length + pixel_length + profile_length; + data = g_malloc0 (data_length); + memcpy (data, encoding, encoding_length); + memcpy (data + encoding_length, pixel, pixel_length); + if (profile_length > 0) + memcpy (data + encoding_length + pixel_length, profile_data, profile_length); gtk_selection_data_set (selection, gtk_selection_data_get_target (selection), - 16, (const guchar *) vals, 8); + 8, (const guchar *) data, data_length); } -gboolean -gimp_selection_data_get_color (GtkSelectionData *selection, - GimpRGB *color) +GeglColor * +gimp_selection_data_get_color (GtkSelectionData *selection) { - const guint16 *color_vals; + GeglColor *color; + const guchar *data; + gint data_length; + const Babl *format; + const gchar *encoding; + gint encoding_length; + const guchar *pixel; + gint pixel_length; + const guint8 *profile_data = NULL; + int profile_length = 0; g_return_val_if_fail (selection != NULL, FALSE); - g_return_val_if_fail (color != NULL, FALSE); - if (gtk_selection_data_get_format (selection) != 16 || - gtk_selection_data_get_length (selection) != 8) + data = gtk_selection_data_get_data (selection); + data_length = gtk_selection_data_get_length (selection); + encoding = (const gchar *) data; + /* gtk_selection_data_set() ensured the data is NUL-terminated so in the + * worst case, strlen() would not read out of bounds. + */ + encoding_length = strlen (encoding) + 1; + if (! babl_format_exists ((const char *) data)) { - g_warning ("Received invalid color data!"); - return FALSE; + g_critical ("%s: received invalid color format: \"%s\"!", G_STRFUNC, encoding); + return NULL; } - color_vals = (const guint16 *) gtk_selection_data_get_data (selection); + format = babl_format (encoding); + pixel_length = babl_format_get_bytes_per_pixel (format); + if (data_length < encoding_length + pixel_length) + { + g_critical ("%s: received invalid color data of %d bytes " + "(expected: %d bytes or more)!", + G_STRFUNC, data_length, encoding_length + pixel_length); + return NULL; + } + pixel = data + encoding_length; + profile_length = data_length - encoding_length - pixel_length; + if (profile_length > 0) + { + GimpColorProfile *profile; + GError *error = NULL; - gimp_rgba_set_uchar (color, - (guchar) (color_vals[0] >> 8), - (guchar) (color_vals[1] >> 8), - (guchar) (color_vals[2] >> 8), - (guchar) (color_vals[3] >> 8)); + profile_data = pixel + pixel_length; - return TRUE; + profile = gimp_color_profile_new_from_icc_profile (profile_data, profile_length, &error); + if (profile) + { + const Babl *space; + + space = gimp_color_profile_get_space (profile, + GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC, + &error); + + if (space) + { + format = babl_format_with_space (encoding, space); + } + else + { + g_warning ("%s: failed to create Babl space for profile: %s", + G_STRFUNC, error->message); + g_clear_error (&error); + } + g_object_unref (profile); + } + else + { + g_warning ("%s: received invalid profile data of %d bytes: %s", + G_STRFUNC, profile_length, error->message); + g_clear_error (&error); + } + } + + color = gegl_color_new (NULL); + gegl_color_set_pixel (color, format, pixel); + + return color; } void diff --git a/app/widgets/gimpselectiondata.h b/app/widgets/gimpselectiondata.h index 891429095c..ed028b55fd 100644 --- a/app/widgets/gimpselectiondata.h +++ b/app/widgets/gimpselectiondata.h @@ -29,9 +29,8 @@ GList * gimp_selection_data_get_uri_list (GtkSelectionData *selection); /* color */ void gimp_selection_data_set_color (GtkSelectionData *selection, - const GimpRGB *color); -gboolean gimp_selection_data_get_color (GtkSelectionData *selection, - GimpRGB *color); + GeglColor *color); +GeglColor * gimp_selection_data_get_color (GtkSelectionData *selection); /* image (xcf) */ diff --git a/app/widgets/gimpselectioneditor.c b/app/widgets/gimpselectioneditor.c index 24a6d4e0be..df9395c223 100644 --- a/app/widgets/gimpselectioneditor.c +++ b/app/widgets/gimpselectioneditor.c @@ -67,7 +67,7 @@ static gboolean gimp_selection_view_button_press (GtkWidget *widget, static void gimp_selection_editor_drop_color (GtkWidget *widget, gint x, gint y, - const GimpRGB *color, + GeglColor *color, gpointer data); static void gimp_selection_editor_mask_changed (GimpImage *image, @@ -303,19 +303,17 @@ gimp_selection_view_button_press (GtkWidget *widget, } static void -gimp_selection_editor_drop_color (GtkWidget *widget, - gint x, - gint y, - /* TODO: should drop a GeglColor */ - const GimpRGB *rgb, - gpointer data) +gimp_selection_editor_drop_color (GtkWidget *widget, + gint x, + gint y, + GeglColor *color, + gpointer data) { GimpImageEditor *editor = GIMP_IMAGE_EDITOR (data); GimpToolInfo *tool_info; GimpSelectionOptions *sel_options; GimpRegionSelectOptions *options; GList *drawables; - GeglColor *color; if (! editor->image) return; @@ -333,8 +331,6 @@ gimp_selection_editor_drop_color (GtkWidget *widget, if (! drawables) return; - color = gegl_color_new ("black"); - gegl_color_set_rgba_with_space (color, rgb->r, rgb->g, rgb->b, rgb->a, NULL); gimp_channel_select_by_color (gimp_image_get_mask (editor->image), drawables, options->sample_merged, @@ -349,7 +345,6 @@ gimp_selection_editor_drop_color (GtkWidget *widget, sel_options->feather_radius); gimp_image_flush (editor->image); g_list_free (drawables); - g_object_unref (color); } static void