static void gimp_display_shell_drop_buffer (GtkWidget *widget, gint drop_x, gint drop_y, GimpViewable *viewable, gpointer data) { GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data); GimpImage *image = gimp_display_get_image (shell->display); GimpDrawable *drawable; GimpBuffer *buffer; gint x, y, width, height; GIMP_LOG (DND, NULL); if (shell->display->gimp->busy) return; if (! image) { image = gimp_image_new_from_buffer (shell->display->gimp, NULL, GIMP_BUFFER (viewable)); gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0); g_object_unref (image); return; } drawable = gimp_image_get_active_drawable (image); if (drawable) { if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display), GIMP_MESSAGE_ERROR, _("Cannot modify the pixels of layer groups.")); return; } if (gimp_item_is_content_locked (GIMP_ITEM (drawable))) { gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display), GIMP_MESSAGE_ERROR, _("The active layer's pixels are locked.")); return; } } buffer = GIMP_BUFFER (viewable); gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height); /* FIXME: popup a menu for selecting "Paste Into" */ gimp_edit_paste (image, drawable, buffer, FALSE, x, y, width, height); gimp_display_shell_dnd_flush (shell, image); }
static void gimp_display_shell_drop_buffer (GtkWidget *widget, gint drop_x, gint drop_y, GimpViewable *viewable, gpointer data) { GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data); GimpImage *image = shell->display->image; GimpBuffer *buffer; gint x, y, width, height; GIMP_LOG (DND, NULL); if (shell->display->gimp->busy) return; if (! image) return; buffer = GIMP_BUFFER (viewable); gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height); /* FIXME: popup a menu for selecting "Paste Into" */ gimp_edit_paste (image, gimp_image_get_active_drawable (image), buffer, FALSE, x, y, width, height); gimp_display_shell_dnd_flush (shell, image); }
static GimpTempBuf * gimp_buffer_get_new_preview (GimpViewable *viewable, GimpContext *context, gint width, gint height) { GimpBuffer *buffer = GIMP_BUFFER (viewable); const Babl *format = gimp_buffer_get_format (buffer); GimpTempBuf *preview; if (babl_format_is_palette (format)) format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8_GAMMA, babl_format_has_alpha (format)); else format = gimp_babl_format (gimp_babl_format_get_base_type (format), gimp_babl_precision (GIMP_COMPONENT_TYPE_U8, gimp_babl_format_get_linear (format)), babl_format_has_alpha (format)); preview = gimp_temp_buf_new (width, height, format); gegl_buffer_get (buffer->buffer, GEGL_RECTANGLE (0, 0, width, height), MIN ((gdouble) width / (gdouble) gimp_buffer_get_width (buffer), (gdouble) height / (gdouble) gimp_buffer_get_height (buffer)), format, gimp_temp_buf_get_data (preview), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); return preview; }
static TempBuf * gimp_buffer_get_new_preview (GimpViewable *viewable, GimpContext *context, gint width, gint height) { GimpBuffer *buffer = GIMP_BUFFER (viewable); return tile_manager_get_preview (buffer->tiles, width, height); }
static GimpColorProfile * gimp_buffer_color_managed_get_color_profile (GimpColorManaged *managed) { GimpBuffer *buffer = GIMP_BUFFER (managed); if (buffer->color_profile) return buffer->color_profile; return gimp_babl_format_get_color_profile (gimp_buffer_get_format (buffer)); }
static void gimp_buffer_finalize (GObject *object) { GimpBuffer *buffer = GIMP_BUFFER (object); g_clear_object (&buffer->buffer); gimp_buffer_set_color_profile (buffer, NULL); G_OBJECT_CLASS (parent_class)->finalize (object); }
static gchar * gimp_buffer_get_description (GimpViewable *viewable, gchar **tooltip) { GimpBuffer *buffer = GIMP_BUFFER (viewable); return g_strdup_printf ("%s (%d × %d)", GIMP_OBJECT (buffer)->name, gimp_buffer_get_width (buffer), gimp_buffer_get_height (buffer)); }
static const guint8 * gimp_buffer_color_managed_get_icc_profile (GimpColorManaged *managed, gsize *len) { GimpBuffer *buffer = GIMP_BUFFER (managed); if (buffer->color_profile) return gimp_color_profile_get_icc_profile (buffer->color_profile, len); return NULL; }
static gboolean gimp_buffer_get_size (GimpViewable *viewable, gint *width, gint *height) { GimpBuffer *buffer = GIMP_BUFFER (viewable); *width = gimp_buffer_get_width (buffer); *height = gimp_buffer_get_height (buffer); return TRUE; }
static gint64 gimp_buffer_get_memsize (GimpObject *object, gint64 *gui_size) { GimpBuffer *buffer = GIMP_BUFFER (object); gint64 memsize = 0; memsize += gimp_gegl_buffer_get_memsize (buffer->buffer); return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object, gui_size); }
static void gimp_buffer_finalize (GObject *object) { GimpBuffer *buffer = GIMP_BUFFER (object); if (buffer->buffer) { g_object_unref (buffer->buffer); buffer->buffer = NULL; } G_OBJECT_CLASS (parent_class)->finalize (object); }
static void gimp_buffer_finalize (GObject *object) { GimpBuffer *buffer = GIMP_BUFFER (object); if (buffer->tiles) { tile_manager_unref (buffer->tiles); buffer->tiles = NULL; } G_OBJECT_CLASS (parent_class)->finalize (object); }
static gint64 gimp_buffer_get_memsize (GimpObject *object, gint64 *gui_size) { GimpBuffer *buffer = GIMP_BUFFER (object); gint64 memsize = 0; if (buffer->tiles) memsize += tile_manager_get_memsize (buffer->tiles, FALSE); return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object, gui_size); }
static void gimp_toolbox_drop_buffer (GtkWidget *widget, gint x, gint y, GimpViewable *viewable, gpointer data) { GimpContext *context = GIMP_CONTEXT (data); GimpImage *image; if (context->gimp->busy) return; image = gimp_image_new_from_buffer (context->gimp, NULL, GIMP_BUFFER (viewable)); gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0); g_object_unref (image); }
static void gimp_buffer_get_preview_size (GimpViewable *viewable, gint size, gboolean is_popup, gboolean dot_for_dot, gint *width, gint *height) { GimpBuffer *buffer = GIMP_BUFFER (viewable); gimp_viewable_calc_preview_size (gimp_buffer_get_width (buffer), gimp_buffer_get_height (buffer), size, size, dot_for_dot, 1.0, 1.0, width, height, NULL); }
GimpImage * gimp_edit_paste_as_new_image (Gimp *gimp, GimpObject *paste) { GimpImage *image = NULL; g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (paste) || GIMP_IS_BUFFER (paste), NULL); if (GIMP_IS_IMAGE (paste)) { image = gimp_image_duplicate (GIMP_IMAGE (paste)); } else if (GIMP_IS_BUFFER (paste)) { image = gimp_image_new_from_buffer (gimp, GIMP_BUFFER (paste)); } return image; }
static gboolean gimp_buffer_get_popup_size (GimpViewable *viewable, gint width, gint height, gboolean dot_for_dot, gint *popup_width, gint *popup_height) { GimpBuffer *buffer; gint buffer_width; gint buffer_height; buffer = GIMP_BUFFER (viewable); buffer_width = gimp_buffer_get_width (buffer); buffer_height = gimp_buffer_get_height (buffer); if (buffer_width > width || buffer_height > height) { gboolean scaling_up; gimp_viewable_calc_preview_size (buffer_width, buffer_height, width * 2, height * 2, dot_for_dot, 1.0, 1.0, popup_width, popup_height, &scaling_up); if (scaling_up) { *popup_width = buffer_width; *popup_height = buffer_height; } return TRUE; } return FALSE; }
static void gimp_display_shell_drop_buffer (GtkWidget *widget, gint drop_x, gint drop_y, GimpViewable *viewable, gpointer data) { GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data); GimpImage *image = gimp_display_get_image (shell->display); GimpDrawable *drawable; GimpBuffer *buffer; GimpPasteType paste_type; gint x, y, width, height; GIMP_LOG (DND, NULL); if (shell->display->gimp->busy) return; if (! image) { image = gimp_image_new_from_buffer (shell->display->gimp, NULL, GIMP_BUFFER (viewable)); gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0, G_OBJECT (gtk_widget_get_screen (widget)), gimp_widget_get_monitor (widget)); g_object_unref (image); return; } paste_type = GIMP_PASTE_TYPE_FLOATING; drawable = gimp_image_get_active_drawable (image); if (drawable) { if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display), GIMP_MESSAGE_INFO, _("Pasted as new layer because the " "target is a layer group.")); paste_type = GIMP_PASTE_TYPE_NEW_LAYER; } else if (gimp_item_is_content_locked (GIMP_ITEM (drawable))) { gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display), GIMP_MESSAGE_ERROR, _("Pasted as new layer because the " "target's pixels are locked.")); paste_type = GIMP_PASTE_TYPE_NEW_LAYER; } } buffer = GIMP_BUFFER (viewable); gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height); /* FIXME: popup a menu for selecting "Paste Into" */ gimp_edit_paste (image, drawable, GIMP_OBJECT (buffer), paste_type, x, y, width, height); gimp_display_shell_dnd_flush (shell, image); }
GimpLayer * gimp_edit_paste (GimpImage *image, GimpDrawable *drawable, GimpObject *paste, GimpPasteType paste_type, gint viewport_x, gint viewport_y, gint viewport_width, gint viewport_height) { GimpLayer *layer = NULL; const Babl *floating_format; gint offset_x; gint offset_y; g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (drawable == NULL || gimp_item_is_attached (GIMP_ITEM (drawable)), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (paste) || GIMP_IS_BUFFER (paste), NULL); /* change paste type to NEW_LAYER for cases where we can't attach a * floating selection */ if (! drawable || gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) || gimp_item_is_content_locked (GIMP_ITEM (drawable))) { paste_type = GIMP_PASTE_TYPE_NEW_LAYER; } /* floating pastes always have the pasted-to drawable's format with * alpha; if drawable == NULL, user is pasting into an empty image */ if (drawable) floating_format = gimp_drawable_get_format_with_alpha (drawable); else floating_format = gimp_image_get_layer_format (image, TRUE); if (GIMP_IS_IMAGE (paste)) { GType layer_type; layer = gimp_image_get_layer_iter (GIMP_IMAGE (paste))->data; switch (paste_type) { case GIMP_PASTE_TYPE_FLOATING: case GIMP_PASTE_TYPE_FLOATING_INTO: /* when pasting as floating selection, force creation of a * plain layer, so gimp_item_convert() will collapse a * group layer */ layer_type = GIMP_TYPE_LAYER; break; case GIMP_PASTE_TYPE_NEW_LAYER: layer_type = G_TYPE_FROM_INSTANCE (layer); break; default: g_return_val_if_reached (NULL); } layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (layer), image, layer_type)); switch (paste_type) { case GIMP_PASTE_TYPE_FLOATING: case GIMP_PASTE_TYPE_FLOATING_INTO: /* when pasting as floating selection, get rid of the layer mask, * and make sure the layer has the right format */ if (gimp_layer_get_mask (layer)) gimp_layer_apply_mask (layer, GIMP_MASK_DISCARD, FALSE); if (gimp_drawable_get_format (GIMP_DRAWABLE (layer)) != floating_format) { gimp_drawable_convert_type (GIMP_DRAWABLE (layer), image, gimp_drawable_get_base_type (drawable), gimp_drawable_get_precision (drawable), TRUE, NULL, GEGL_DITHER_NONE, GEGL_DITHER_NONE, FALSE, NULL); } break; default: break; } } else if (GIMP_IS_BUFFER (paste)) { layer = gimp_layer_new_from_buffer (GIMP_BUFFER (paste), image, floating_format, _("Pasted Layer"), GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE); } if (! layer) return NULL; gimp_edit_get_paste_offset (image, drawable, GIMP_OBJECT (layer), viewport_x, viewport_y, viewport_width, viewport_height, &offset_x, &offset_y); gimp_item_set_offset (GIMP_ITEM (layer), offset_x, offset_y); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE, C_("undo-type", "Paste")); switch (paste_type) { case GIMP_PASTE_TYPE_FLOATING: /* if there is a selection mask clear it - this might not * always be desired, but in general, it seems like the correct * behavior */ if (! gimp_channel_is_empty (gimp_image_get_mask (image))) gimp_channel_clear (gimp_image_get_mask (image), NULL, TRUE); /* fall thru */ case GIMP_PASTE_TYPE_FLOATING_INTO: floating_sel_attach (layer, drawable); break; case GIMP_PASTE_TYPE_NEW_LAYER: { GimpLayer *parent = NULL; gint position = 0; /* always add on top of the passed layer, where we would * attach a floating selection */ if (GIMP_IS_LAYER (drawable)) { parent = gimp_layer_get_parent (GIMP_LAYER (drawable)); position = gimp_item_get_index (GIMP_ITEM (drawable)); } gimp_image_add_layer (image, layer, parent, position, TRUE); } break; } gimp_image_undo_group_end (image); return layer; }
static GdkPixbuf * gimp_buffer_get_new_pixbuf (GimpViewable *viewable, GimpContext *context, gint width, gint height) { GimpBuffer *buffer = GIMP_BUFFER (viewable); GdkPixbuf *pixbuf; gdouble scale; pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); scale = MIN ((gdouble) width / (gdouble) gimp_buffer_get_width (buffer), (gdouble) height / (gdouble) gimp_buffer_get_height (buffer)); if (buffer->color_profile) { GimpColorProfile *srgb_profile; GimpTempBuf *temp_buf; GeglBuffer *src_buf; GeglBuffer *dest_buf; srgb_profile = gimp_color_profile_new_rgb_srgb (); temp_buf = gimp_temp_buf_new (width, height, gimp_buffer_get_format (buffer)); gegl_buffer_get (buffer->buffer, GEGL_RECTANGLE (0, 0, width, height), scale, gimp_temp_buf_get_format (temp_buf), gimp_temp_buf_get_data (temp_buf), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP); src_buf = gimp_temp_buf_create_buffer (temp_buf); dest_buf = gimp_pixbuf_create_buffer (pixbuf); gimp_temp_buf_unref (temp_buf); gimp_gegl_convert_color_profile (src_buf, GEGL_RECTANGLE (0, 0, width, height), buffer->color_profile, dest_buf, GEGL_RECTANGLE (0, 0, 0, 0), srgb_profile, GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL, TRUE, NULL); g_object_unref (src_buf); g_object_unref (dest_buf); g_object_unref (srgb_profile); } else { gegl_buffer_get (buffer->buffer, GEGL_RECTANGLE (0, 0, width, height), scale, gimp_pixbuf_get_format (pixbuf), gdk_pixbuf_get_pixels (pixbuf), gdk_pixbuf_get_rowstride (pixbuf), GEGL_ABYSS_CLAMP); } return pixbuf; }