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); }
/** * gimp_image_scale_check: * @image: A #GimpImage. * @new_width: The new width. * @new_height: The new height. * @max_memsize: The maximum new memory size. * @new_memsize: The new memory size. * * Inventory the layer list in image and check that it may be * scaled to @new_height and @new_width without problems. * * Return value: #GIMP_IMAGE_SCALE_OK if scaling the image will shrink none * of its layers completely away, and the new image size * is smaller than @max_memsize. * #GIMP_IMAGE_SCALE_TOO_SMALL if scaling would remove some * existing layers. * #GIMP_IMAGE_SCALE_TOO_BIG if the new image size would * exceed the maximum specified in the preferences. **/ GimpImageScaleCheckType gimp_image_scale_check (GimpImage *image, gint new_width, gint new_height, gint64 max_memsize, gint64 *new_memsize) { GList *all_layers; GList *list; gint64 current_size; gint64 undo_size; gint64 redo_size; gint64 new_size; g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_IMAGE_SCALE_TOO_SMALL); g_return_val_if_fail (new_memsize != NULL, GIMP_IMAGE_SCALE_TOO_SMALL); current_size = gimp_object_get_memsize (GIMP_OBJECT (image), NULL); new_size = gimp_image_estimate_memsize (image, gimp_image_get_component_type (image), new_width, new_height); undo_size = gimp_object_get_memsize (GIMP_OBJECT (gimp_image_get_undo_stack (image)), NULL); redo_size = gimp_object_get_memsize (GIMP_OBJECT (gimp_image_get_redo_stack (image)), NULL); current_size -= undo_size + redo_size; new_size -= undo_size + redo_size; GIMP_LOG (IMAGE_SCALE, "old_size = %"G_GINT64_FORMAT" new_size = %"G_GINT64_FORMAT, current_size, new_size); *new_memsize = new_size; if (new_size > current_size && new_size > max_memsize) return GIMP_IMAGE_SCALE_TOO_BIG; all_layers = gimp_image_get_layer_list (image); for (list = all_layers; list; list = g_list_next (list)) { GimpItem *item = list->data; /* group layers are updated automatically */ if (gimp_viewable_get_children (GIMP_VIEWABLE (item))) continue; if (! gimp_item_check_scaling (item, new_width, new_height)) { g_list_free (all_layers); return GIMP_IMAGE_SCALE_TOO_SMALL; } } g_list_free (all_layers); return GIMP_IMAGE_SCALE_OK; }
static gboolean gimp_bucket_fill_tool_initialize (GimpTool *tool, GimpDisplay *display, GError **error) { GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); if (! GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error)) { return FALSE; } if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("Cannot modify the pixels of layer groups.")); return FALSE; } if (gimp_item_is_content_locked (GIMP_ITEM (drawable))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("The active layer's pixels are locked.")); return FALSE; } return TRUE; }
static void gimp_blend_tool_cursor_update (GimpTool *tool, const GimpCoords *coords, GdkModifierType state, GimpDisplay *display) { GimpBlendTool *blend_tool = GIMP_BLEND_TOOL (tool); GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE; blend_tool->mouse_x = coords->x; blend_tool->mouse_y = coords->y; if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) || gimp_item_is_content_locked (GIMP_ITEM (drawable)) || ! gimp_item_is_visible (GIMP_ITEM (drawable))) { modifier = GIMP_CURSOR_MODIFIER_BAD; } else if (gimp_blend_tool_is_shapeburst (blend_tool)) { modifier = GIMP_CURSOR_MODIFIER_PLUS; } else if (gimp_blend_tool_get_point_under_cursor (blend_tool)) { modifier = GIMP_CURSOR_MODIFIER_MOVE; } gimp_tool_control_set_cursor_modifier (tool->control, modifier); GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display); }
static void gimp_view_renderer_layer_render (GimpViewRenderer *renderer, GtkWidget *widget) { const gchar *icon_name = NULL; if (gimp_layer_is_floating_sel (GIMP_LAYER (renderer->viewable))) { icon_name = GIMP_STOCK_FLOATING_SELECTION; } else if (gimp_item_is_text_layer (GIMP_ITEM (renderer->viewable))) { icon_name = gimp_viewable_get_icon_name (renderer->viewable); } else { GimpContainer *children = gimp_viewable_get_children (renderer->viewable); if (children && gimp_container_get_n_children (children) == 0) icon_name = "folder"; } if (icon_name) gimp_view_renderer_render_icon (renderer, widget, icon_name); else GIMP_VIEW_RENDERER_CLASS (parent_class)->render (renderer, widget); }
static void gimp_paint_tool_cursor_update (GimpTool *tool, const GimpCoords *coords, GdkModifierType state, GimpDisplay *display) { GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool); GimpCursorModifier modifier; GimpCursorModifier toggle_modifier; GimpCursorModifier old_modifier; GimpCursorModifier old_toggle_modifier; modifier = tool->control->cursor_modifier; toggle_modifier = tool->control->toggle_cursor_modifier; old_modifier = modifier; old_toggle_modifier = toggle_modifier; if (! gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (tool))) { GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) || gimp_item_is_content_locked (GIMP_ITEM (drawable)) || ! gimp_item_is_visible (GIMP_ITEM (drawable))) { modifier = GIMP_CURSOR_MODIFIER_BAD; toggle_modifier = GIMP_CURSOR_MODIFIER_BAD; } if (! paint_tool->show_cursor && modifier != GIMP_CURSOR_MODIFIER_BAD) { gimp_tool_set_cursor (tool, display, GIMP_CURSOR_NONE, GIMP_TOOL_CURSOR_NONE, GIMP_CURSOR_MODIFIER_NONE); return; } gimp_tool_control_set_cursor_modifier (tool->control, modifier); gimp_tool_control_set_toggle_cursor_modifier (tool->control, toggle_modifier); } GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display); /* reset old stuff here so we are not interferring with the modifiers * set by our subclasses */ gimp_tool_control_set_cursor_modifier (tool->control, old_modifier); gimp_tool_control_set_toggle_cursor_modifier (tool->control, old_toggle_modifier); }
static void gimp_display_shell_dnd_bucket_fill (GimpDisplayShell *shell, GimpBucketFillMode fill_mode, const GimpRGB *color, GimpPattern *pattern) { GimpImage *image = gimp_display_get_image (shell->display); GimpDrawable *drawable; if (shell->display->gimp->busy) return; if (! image) return; drawable = gimp_image_get_active_drawable (image); if (! drawable) return; 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; } /* FIXME: there should be a virtual method for this that the * GimpTextLayer can override. */ if (color && gimp_item_is_text_layer (GIMP_ITEM (drawable))) { gimp_text_layer_set (GIMP_TEXT_LAYER (drawable), NULL, "color", color, NULL); } else { gimp_edit_fill_full (image, drawable, color, pattern, GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE, pattern ? C_("undo-type", "Drop pattern to layer") : C_("undo-type", "Drop color to layer")); } gimp_display_shell_dnd_flush (shell, image); }
static void gimp_display_shell_dnd_fill (GimpDisplayShell *shell, GimpFillOptions *options, const gchar *undo_desc) { GimpImage *image = gimp_display_get_image (shell->display); GimpDrawable *drawable; if (shell->display->gimp->busy) return; if (! image) return; drawable = gimp_image_get_active_drawable (image); if (! drawable) return; 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; } /* FIXME: there should be a virtual method for this that the * GimpTextLayer can override. */ if (gimp_fill_options_get_style (options) == GIMP_FILL_STYLE_SOLID && gimp_item_is_text_layer (GIMP_ITEM (drawable))) { GimpRGB color; gimp_context_get_foreground (GIMP_CONTEXT (options), &color); gimp_text_layer_set (GIMP_TEXT_LAYER (drawable), NULL, "color", &color, NULL); } else { gimp_edit_fill (image, drawable, options, undo_desc); } gimp_display_shell_dnd_flush (shell, image); }
static GimpValueArray * flip_invoker (GimpProcedure *procedure, Gimp *gimp, GimpContext *context, GimpProgress *progress, const GimpValueArray *args, GError **error) { gboolean success = TRUE; GimpValueArray *return_vals; GimpDrawable *drawable; gint32 flip_type; drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp); flip_type = g_value_get_enum (gimp_value_array_index (args, 1)); if (success) { gint x, y, width, height; success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error); if (success && gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) { gdouble axis; gimp_transform_get_flip_axis (x, y, width, height, flip_type, TRUE, &axis); if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) && ! gimp_channel_is_empty (gimp_image_get_mask (gimp_item_get_image (GIMP_ITEM (drawable))))) { if (! gimp_drawable_transform_flip (drawable, context, flip_type, axis, FALSE)) { success = FALSE; } } else { gimp_item_flip (GIMP_ITEM (drawable), context, flip_type, axis, FALSE); } } } return_vals = gimp_procedure_get_return_values (procedure, success, error ? *error : NULL); if (success) gimp_value_set_drawable (gimp_value_array_index (return_vals, 1), drawable); return return_vals; }
void filters_actions_update (GimpActionGroup *group, gpointer data) { GimpImage *image; GimpDrawable *drawable = NULL; gboolean writable = FALSE; gboolean gray = FALSE; gboolean alpha = FALSE; image = action_data_get_image (data); if (image) { drawable = gimp_image_get_active_drawable (image); if (drawable) { GimpItem *item; alpha = gimp_drawable_has_alpha (drawable); gray = gimp_drawable_is_gray (drawable); if (GIMP_IS_LAYER_MASK (drawable)) item = GIMP_ITEM (gimp_layer_mask_get_layer (GIMP_LAYER_MASK (drawable))); else item = GIMP_ITEM (drawable); writable = ! gimp_item_is_content_locked (item); if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) writable = FALSE; } } #define SET_SENSITIVE(action,condition) \ gimp_action_group_set_action_sensitive (group, action, (condition) != 0) SET_SENSITIVE ("filters-color-reduction", writable); SET_SENSITIVE ("filters-color-temperature", writable && !gray); SET_SENSITIVE ("filters-color-to-alpha", writable && !gray && alpha); SET_SENSITIVE ("filters-difference-of-gaussians", writable); SET_SENSITIVE ("filters-gaussian-blur", writable); SET_SENSITIVE ("filters-laplace", writable); SET_SENSITIVE ("filters-lens-distortion", writable); SET_SENSITIVE ("filters-pixelize", writable); SET_SENSITIVE ("filters-polar-coordinates", writable); SET_SENSITIVE ("filters-ripple", writable); SET_SENSITIVE ("filters-sobel", writable); SET_SENSITIVE ("filters-semi-flatten", writable && alpha); SET_SENSITIVE ("filters-threshold-alpha", writable && alpha); SET_SENSITIVE ("filters-unsharp-mask", writable); #undef SET_SENSITIVE }
void select_actions_update (GimpActionGroup *group, gpointer data) { GimpImage *image = action_data_get_image (data); GimpDrawable *drawable = NULL; gboolean fs = FALSE; gboolean sel = FALSE; gboolean writable = FALSE; gboolean children = FALSE; if (image) { drawable = gimp_image_get_active_drawable (image); if (drawable) { writable = ! gimp_item_is_content_locked (GIMP_ITEM (drawable)); if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) children = TRUE; } fs = (gimp_image_get_floating_selection (image) != NULL); sel = ! gimp_channel_is_empty (gimp_image_get_mask (image)); } #define SET_SENSITIVE(action,condition) \ gimp_action_group_set_action_sensitive (group, action, (condition) != 0) SET_SENSITIVE ("select-all", drawable); SET_SENSITIVE ("select-none", drawable && sel); SET_SENSITIVE ("select-invert", drawable); SET_SENSITIVE ("select-float", writable && !children && sel); SET_SENSITIVE ("select-feather", drawable && sel); SET_SENSITIVE ("select-sharpen", drawable && sel); SET_SENSITIVE ("select-shrink", drawable && sel); SET_SENSITIVE ("select-grow", drawable && sel); SET_SENSITIVE ("select-border", drawable && sel); SET_SENSITIVE ("select-flood", drawable && sel); SET_SENSITIVE ("select-save", drawable && !fs); SET_SENSITIVE ("select-stroke", writable && !children && sel); SET_SENSITIVE ("select-stroke-last-values", writable && !children && sel); #undef SET_SENSITIVE }
static gboolean gimp_blend_tool_initialize (GimpTool *tool, GimpDisplay *display, GError **error) { GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (tool); if (! GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error)) { return FALSE; } if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("Cannot modify the pixels of layer groups.")); return FALSE; } if (gimp_item_is_content_locked (GIMP_ITEM (drawable))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("The active layer's pixels are locked.")); return FALSE; } if (! gimp_item_is_visible (GIMP_ITEM (drawable))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("The active layer is not visible.")); return FALSE; } if (! gimp_context_get_gradient (GIMP_CONTEXT (options))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("No gradient available for use with this tool.")); return FALSE; } return TRUE; }
gboolean gimp_pdb_item_is_not_group (GimpItem *item, GError **error) { g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if (gimp_viewable_get_children (GIMP_VIEWABLE (item))) { g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT, _("Item '%s' (%d) cannot be modified because it " "is a group item"), gimp_object_get_name (item), gimp_item_get_ID (item)); return FALSE; } return TRUE; }
static void gimp_warp_tool_cursor_update (GimpTool *tool, const GimpCoords *coords, GdkModifierType state, GimpDisplay *display) { GimpWarpOptions *options = GIMP_WARP_TOOL_GET_OPTIONS (tool); GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_PLUS; if (display == tool->display) { /* FIXME have better cursors */ switch (options->behavior) { case GIMP_WARP_BEHAVIOR_MOVE: case GEGL_WARP_BEHAVIOR_GROW: case GEGL_WARP_BEHAVIOR_SHRINK: case GEGL_WARP_BEHAVIOR_SWIRL_CW: case GEGL_WARP_BEHAVIOR_SWIRL_CCW: case GEGL_WARP_BEHAVIOR_ERASE: case GEGL_WARP_BEHAVIOR_SMOOTH: modifier = GIMP_CURSOR_MODIFIER_MOVE; break; } } else { GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) || gimp_item_is_content_locked (GIMP_ITEM (drawable)) || ! gimp_item_is_visible (GIMP_ITEM (drawable))) { modifier = GIMP_CURSOR_MODIFIER_BAD; } } gimp_tool_control_set_cursor_modifier (tool->control, modifier); GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display); }
static void gimp_blend_tool_cursor_update (GimpTool *tool, const GimpCoords *coords, GdkModifierType state, GimpDisplay *display) { GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE; if (gimp_drawable_is_indexed (drawable) || gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) || gimp_item_is_content_locked (GIMP_ITEM (drawable))) { modifier = GIMP_CURSOR_MODIFIER_BAD; } gimp_tool_control_set_cursor_modifier (tool->control, modifier); GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display); }
static void gimp_bucket_fill_tool_cursor_update (GimpTool *tool, const GimpCoords *coords, GdkModifierType state, GimpDisplay *display) { GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool); GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_BAD; GimpImage *image = gimp_display_get_image (display); if (gimp_image_coords_in_active_pickable (image, coords, options->sample_merged, TRUE)) { GimpDrawable *drawable = gimp_image_get_active_drawable (image); if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) && ! gimp_item_is_content_locked (GIMP_ITEM (drawable)) && gimp_item_is_visible (GIMP_ITEM (drawable))) { switch (options->fill_mode) { case GIMP_BUCKET_FILL_FG: modifier = GIMP_CURSOR_MODIFIER_FOREGROUND; break; case GIMP_BUCKET_FILL_BG: modifier = GIMP_CURSOR_MODIFIER_BACKGROUND; break; case GIMP_BUCKET_FILL_PATTERN: modifier = GIMP_CURSOR_MODIFIER_PATTERN; break; } } } gimp_tool_control_set_cursor_modifier (tool->control, modifier); GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display); }
static gboolean gimp_drawable_tree_view_drop_possible (GimpContainerTreeView *tree_view, GimpDndType src_type, GimpViewable *src_viewable, GimpViewable *dest_viewable, GtkTreePath *drop_path, GtkTreeViewDropPosition drop_pos, GtkTreeViewDropPosition *return_drop_pos, GdkDragAction *return_drag_action) { if (GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_possible (tree_view, src_type, src_viewable, dest_viewable, drop_path, drop_pos, return_drop_pos, return_drag_action)) { if (src_type == GIMP_DND_TYPE_COLOR || src_type == GIMP_DND_TYPE_PATTERN) { if (! dest_viewable || gimp_item_is_content_locked (GIMP_ITEM (dest_viewable)) || gimp_viewable_get_children (GIMP_VIEWABLE (dest_viewable))) return FALSE; if (return_drop_pos) { *return_drop_pos = GTK_TREE_VIEW_DROP_INTO_OR_AFTER; } } return TRUE; } return FALSE; }
void gimp_display_shell_set_layer_style (GimpDisplayShell *shell, cairo_t *cr, GimpLayer *layer) { cairo_pattern_t *pattern; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (cr != NULL); g_return_if_fail (GIMP_IS_LAYER (layer)); cairo_set_line_width (cr, 1.0); cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); if (gimp_layer_get_mask (layer) && gimp_layer_mask_get_edit (gimp_layer_get_mask (layer))) { pattern = gimp_cairo_stipple_pattern_create (&layer_mask_fg, &layer_mask_bg, 0); } else if (gimp_viewable_get_children (GIMP_VIEWABLE (layer))) { pattern = gimp_cairo_stipple_pattern_create (&layer_group_fg, &layer_group_bg, 0); } else { pattern = gimp_cairo_stipple_pattern_create (&layer_fg, &layer_bg, 0); } cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); }
GimpLayer * gimp_image_merge_down (GimpImage *image, GimpLayer *current_layer, GimpContext *context, GimpMergeType merge_type, GError **error) { GimpLayer *layer; GList *list; GList *layer_list = NULL; GSList *merge_list = NULL; g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_LAYER (current_layer), NULL); g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (current_layer)), NULL); g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); for (list = gimp_item_get_container_iter (GIMP_ITEM (current_layer)); list; list = g_list_next (list)) { layer = list->data; if (layer == current_layer) break; } for (layer_list = g_list_next (list); layer_list; layer_list = g_list_next (layer_list)) { layer = layer_list->data; if (gimp_item_get_visible (GIMP_ITEM (layer))) { if (gimp_viewable_get_children (GIMP_VIEWABLE (layer))) { g_set_error_literal (error, 0, 0, _("Cannot merge down to a layer group.")); return NULL; } if (gimp_item_is_content_locked (GIMP_ITEM (layer))) { g_set_error_literal (error, 0, 0, _("The layer to merge down to is locked.")); return NULL; } merge_list = g_slist_append (NULL, layer); break; } } if (! merge_list) { g_set_error_literal (error, 0, 0, _("There is no visible layer to merge down to.")); return NULL; } merge_list = g_slist_prepend (merge_list, current_layer); gimp_set_busy (image->gimp); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, C_("undo-type", "Merge Down")); layer = gimp_image_merge_layers (image, gimp_item_get_container (GIMP_ITEM (current_layer)), merge_list, context, merge_type); g_slist_free (merge_list); gimp_image_undo_group_end (image); gimp_unset_busy (image->gimp); return layer; }
gboolean gimp_container_tree_view_real_drop_possible (GimpContainerTreeView *tree_view, GimpDndType src_type, GimpViewable *src_viewable, GimpViewable *dest_viewable, GtkTreePath *drop_path, GtkTreeViewDropPosition drop_pos, GtkTreeViewDropPosition *return_drop_pos, GdkDragAction *return_drag_action) { GimpContainerView *view = GIMP_CONTAINER_VIEW (tree_view); GimpContainer *container = gimp_container_view_get_container (view); GimpContainer *src_container = NULL; GimpContainer *dest_container = NULL; gint src_index = -1; gint dest_index = -1; if (src_viewable) { GimpViewable *parent = gimp_viewable_get_parent (src_viewable); if (parent) src_container = gimp_viewable_get_children (parent); else if (gimp_container_have (container, GIMP_OBJECT (src_viewable))) src_container = container; if (src_container) src_index = gimp_container_get_child_index (src_container, GIMP_OBJECT (src_viewable)); } if (dest_viewable) { GimpViewable *parent; /* dropping on the lower third of a group item drops into that group */ if (drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER && gimp_viewable_get_children (dest_viewable)) { parent = dest_viewable; } else { parent = gimp_viewable_get_parent (dest_viewable); } if (parent) dest_container = gimp_viewable_get_children (parent); else if (gimp_container_have (container, GIMP_OBJECT (dest_viewable))) dest_container = container; if (parent == dest_viewable) dest_index = 0; else dest_index = gimp_container_get_child_index (dest_container, GIMP_OBJECT (dest_viewable)); } if (src_viewable && g_type_is_a (G_TYPE_FROM_INSTANCE (src_viewable), gimp_container_get_children_type (container))) { if (src_viewable == dest_viewable) return FALSE; if (src_index == -1 || dest_index == -1) return FALSE; /* don't allow dropping a parent node onto one of its descendants */ if (gimp_viewable_is_ancestor (src_viewable, dest_viewable)) return FALSE; } if (src_container == dest_container) { if (drop_pos == GTK_TREE_VIEW_DROP_BEFORE) { if (dest_index == (src_index + 1)) return FALSE; } else if (drop_pos == GTK_TREE_VIEW_DROP_AFTER) { if (dest_index == (src_index - 1)) return FALSE; } } if (return_drop_pos) *return_drop_pos = drop_pos; if (return_drag_action) { if (src_viewable && g_type_is_a (G_TYPE_FROM_INSTANCE (src_viewable), gimp_container_get_children_type (container))) *return_drag_action = GDK_ACTION_MOVE; else *return_drag_action = GDK_ACTION_COPY; } return TRUE; }
static gboolean gimp_container_tree_view_drop_status (GimpContainerTreeView *tree_view, GdkDragContext *context, gint x, gint y, guint time, GtkTreePath **return_path, GdkAtom *return_atom, GimpDndType *return_src_type, GimpViewable **return_src, GimpViewable **return_dest, GtkTreeViewDropPosition *return_pos) { GimpViewable *src_viewable = NULL; GimpViewable *dest_viewable = NULL; GtkTreePath *drop_path = NULL; GtkTargetList *target_list; GdkAtom target_atom; GimpDndType src_type; GtkTreeViewDropPosition drop_pos = GTK_TREE_VIEW_DROP_BEFORE; GdkDragAction drag_action = 0; if (! gimp_container_view_get_container (GIMP_CONTAINER_VIEW (tree_view)) || ! gimp_container_view_get_reorderable (GIMP_CONTAINER_VIEW (tree_view))) goto drop_impossible; target_list = gtk_drag_dest_get_target_list (GTK_WIDGET (tree_view->view)); target_atom = gtk_drag_dest_find_target (GTK_WIDGET (tree_view->view), context, target_list); if (! gtk_target_list_find (target_list, target_atom, &src_type)) goto drop_impossible; switch (src_type) { case GIMP_DND_TYPE_URI_LIST: case GIMP_DND_TYPE_TEXT_PLAIN: case GIMP_DND_TYPE_NETSCAPE_URL: case GIMP_DND_TYPE_COLOR: case GIMP_DND_TYPE_SVG: case GIMP_DND_TYPE_SVG_XML: case GIMP_DND_TYPE_COMPONENT: case GIMP_DND_TYPE_PIXBUF: break; default: { GtkWidget *src_widget = gtk_drag_get_source_widget (context); if (! src_widget) goto drop_impossible; src_viewable = gimp_dnd_get_drag_data (src_widget); if (! GIMP_IS_VIEWABLE (src_viewable)) goto drop_impossible; } break; } if (gtk_tree_view_get_path_at_pos (tree_view->view, x, y, &drop_path, NULL, NULL, NULL)) { GimpViewRenderer *renderer; GtkTreeIter iter; GdkRectangle cell_area; gtk_tree_model_get_iter (tree_view->model, &iter, drop_path); gtk_tree_model_get (tree_view->model, &iter, GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, -1); dest_viewable = renderer->viewable; g_object_unref (renderer); gtk_tree_view_get_cell_area (tree_view->view, drop_path, NULL, &cell_area); if (gimp_viewable_get_children (dest_viewable)) { if (gtk_tree_view_row_expanded (tree_view->view, drop_path)) { if (y >= (cell_area.y + cell_area.height / 2)) drop_pos = GTK_TREE_VIEW_DROP_INTO_OR_AFTER; else drop_pos = GTK_TREE_VIEW_DROP_BEFORE; } else { if (y >= (cell_area.y + 2 * (cell_area.height / 3))) drop_pos = GTK_TREE_VIEW_DROP_AFTER; else if (y <= (cell_area.y + cell_area.height / 3)) drop_pos = GTK_TREE_VIEW_DROP_BEFORE; else drop_pos = GTK_TREE_VIEW_DROP_INTO_OR_AFTER; } } else { if (y >= (cell_area.y + cell_area.height / 2)) drop_pos = GTK_TREE_VIEW_DROP_AFTER; else drop_pos = GTK_TREE_VIEW_DROP_BEFORE; } } else { GtkTreeIter iter; gint n_children; n_children = gtk_tree_model_iter_n_children (tree_view->model, NULL); if (n_children > 0 && gtk_tree_model_iter_nth_child (tree_view->model, &iter, NULL, n_children - 1)) { GimpViewRenderer *renderer; gtk_tree_model_get (tree_view->model, &iter, GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, -1); drop_path = gtk_tree_model_get_path (tree_view->model, &iter); dest_viewable = renderer->viewable; drop_pos = GTK_TREE_VIEW_DROP_AFTER; g_object_unref (renderer); } } if (dest_viewable || tree_view->priv->dnd_drop_to_empty) { if (GIMP_CONTAINER_TREE_VIEW_GET_CLASS (tree_view)->drop_possible (tree_view, src_type, src_viewable, dest_viewable, drop_path, drop_pos, &drop_pos, &drag_action)) { gdk_drag_status (context, drag_action, time); if (return_path) *return_path = drop_path; else gtk_tree_path_free (drop_path); if (return_atom) *return_atom = target_atom; if (return_src) *return_src = src_viewable; if (return_dest) *return_dest = dest_viewable; if (return_pos) *return_pos = drop_pos; return TRUE; } gtk_tree_path_free (drop_path); } drop_impossible: gdk_drag_status (context, 0, time); return FALSE; }
void gimp_image_resize_with_layers (GimpImage *image, GimpContext *context, gint new_width, gint new_height, gint offset_x, gint offset_y, GimpItemSet layer_set, gboolean resize_text_layers, GimpProgress *progress) { GList *list; GList *resize_layers; gdouble progress_max; gdouble progress_current = 1.0; gint old_width, old_height; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (new_width > 0 && new_height > 0); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); gimp_set_busy (image->gimp); g_object_freeze_notify (G_OBJECT (image)); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_RESIZE, C_("undo-type", "Resize Image")); resize_layers = gimp_image_item_list_get_list (image, NULL, GIMP_ITEM_TYPE_LAYERS, layer_set); progress_max = (gimp_container_get_n_children (gimp_image_get_layers (image)) + gimp_container_get_n_children (gimp_image_get_channels (image)) + gimp_container_get_n_children (gimp_image_get_vectors (image)) + g_list_length (resize_layers) + 1 /* selection */); old_width = gimp_image_get_width (image); old_height = gimp_image_get_height (image); /* Push the image size to the stack */ gimp_image_undo_push_image_size (image, NULL, -offset_x, -offset_y, new_width, new_height); /* Set the new width and height */ g_object_set (image, "width", new_width, "height", new_height, NULL); /* Resize all channels */ for (list = gimp_image_get_channel_iter (image); list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_resize (item, context, new_width, new_height, offset_x, offset_y); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Resize all vectors */ for (list = gimp_image_get_vectors_iter (image); list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_resize (item, context, new_width, new_height, offset_x, offset_y); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Don't forget the selection mask! */ gimp_item_resize (GIMP_ITEM (gimp_image_get_mask (image)), context, new_width, new_height, offset_x, offset_y); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); /* Reposition all layers */ for (list = gimp_image_get_layer_iter (image); list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_translate (item, offset_x, offset_y, TRUE); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Resize all resize_layers to image size */ for (list = resize_layers; list; list = g_list_next (list)) { GimpItem *item = list->data; gint old_offset_x; gint old_offset_y; /* group layers can't be resized here */ if (gimp_viewable_get_children (GIMP_VIEWABLE (item))) continue; if (! resize_text_layers && gimp_item_is_text_layer (item)) continue; gimp_item_get_offset (item, &old_offset_x, &old_offset_y); gimp_item_resize (item, context, new_width, new_height, old_offset_x, old_offset_y); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } g_list_free (resize_layers); /* Reposition or remove all guides */ list = gimp_image_get_guides (image); while (list) { GimpGuide *guide = list->data; gboolean remove_guide = FALSE; gint new_position = gimp_guide_get_position (guide); list = g_list_next (list); switch (gimp_guide_get_orientation (guide)) { case GIMP_ORIENTATION_HORIZONTAL: new_position += offset_y; if (new_position < 0 || new_position > new_height) remove_guide = TRUE; break; case GIMP_ORIENTATION_VERTICAL: new_position += offset_x; if (new_position < 0 || new_position > new_width) remove_guide = TRUE; break; default: break; } if (remove_guide) gimp_image_remove_guide (image, guide, TRUE); else if (new_position != gimp_guide_get_position (guide)) gimp_image_move_guide (image, guide, new_position, TRUE); } /* Reposition or remove sample points */ list = gimp_image_get_sample_points (image); while (list) { GimpSamplePoint *sample_point = list->data; gboolean remove_sample_point = FALSE; gint new_x = sample_point->x; gint new_y = sample_point->y; list = g_list_next (list); new_y += offset_y; if ((sample_point->y < 0) || (sample_point->y > new_height)) remove_sample_point = TRUE; new_x += offset_x; if ((sample_point->x < 0) || (sample_point->x > new_width)) remove_sample_point = TRUE; if (remove_sample_point) gimp_image_remove_sample_point (image, sample_point, TRUE); else if (new_x != sample_point->x || new_y != sample_point->y) gimp_image_move_sample_point (image, sample_point, new_x, new_y, TRUE); } gimp_image_undo_group_end (image); gimp_image_size_changed_detailed (image, offset_x, offset_y, old_width, old_height); g_object_thaw_notify (G_OBJECT (image)); gimp_unset_busy (image->gimp); }
static void gimp_paint_tool_button_press (GimpTool *tool, const GimpCoords *coords, guint32 time, GdkModifierType state, GimpButtonPressType press_type, GimpDisplay *display) { GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool); GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool); GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (tool); GimpPaintCore *core = paint_tool->core; GimpDisplayShell *shell = gimp_display_get_shell (display); GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpCoords curr_coords; gint off_x, off_y; GError *error = NULL; if (gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (tool))) { GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time, state, press_type, display); return; } if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { gimp_tool_message_literal (tool, display, _("Cannot paint on layer groups.")); return; } if (gimp_item_is_content_locked (GIMP_ITEM (drawable))) { gimp_tool_message_literal (tool, display, _("The active layer's pixels are locked.")); return; } if (! gimp_item_is_visible (GIMP_ITEM (drawable))) { gimp_tool_message_literal (tool, display, _("The active layer is not visible.")); return; } curr_coords = *coords; gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); curr_coords.x -= off_x; curr_coords.y -= off_y; if (gimp_draw_tool_is_active (draw_tool)) gimp_draw_tool_stop (draw_tool); if (tool->display && tool->display != display && gimp_display_get_image (tool->display) == image) { /* if this is a different display, but the same image, HACK around * in tool internals AFTER stopping the current draw_tool, so * straight line drawing works across different views of the * same image. */ tool->display = display; } if (! gimp_paint_core_start (core, drawable, paint_options, &curr_coords, &error)) { gimp_tool_message_literal (tool, display, error->message); g_clear_error (&error); return; } if ((display != tool->display) || ! paint_tool->draw_line) { /* if this is a new display, resest the "last stroke's endpoint" * because there is none */ if (display != tool->display) core->start_coords = core->cur_coords; core->last_coords = core->cur_coords; core->distance = 0.0; core->pixel_dist = 0.0; } else if (paint_tool->draw_line) { gboolean constrain = (state & gimp_get_constrain_behavior_mask ()) != 0; /* If shift is down and this is not the first paint * stroke, then draw a line from the last coords to the pointer */ gimp_paint_core_round_line (core, paint_options, constrain); } /* chain up to activate the tool */ GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time, state, press_type, display); /* pause the current selection */ gimp_display_shell_selection_pause (shell); /* Let the specific painting function initialize itself */ gimp_paint_core_paint (core, drawable, paint_options, GIMP_PAINT_STATE_INIT, time); /* Paint to the image */ if (paint_tool->draw_line) { gimp_paint_core_interpolate (core, drawable, paint_options, &core->cur_coords, time); } else { gimp_paint_core_paint (core, drawable, paint_options, GIMP_PAINT_STATE_MOTION, time); } gimp_projection_flush_now (gimp_image_get_projection (image)); gimp_display_flush_now (display); gimp_draw_tool_start (draw_tool, display); }
void filters_actions_update (GimpActionGroup *group, gpointer data) { GimpImage *image; GimpDrawable *drawable = NULL; gboolean writable = FALSE; gboolean gray = FALSE; gboolean alpha = FALSE; image = action_data_get_image (data); if (image) { drawable = gimp_image_get_active_drawable (image); if (drawable) { GimpItem *item; alpha = gimp_drawable_has_alpha (drawable); gray = gimp_drawable_is_gray (drawable); if (GIMP_IS_LAYER_MASK (drawable)) item = GIMP_ITEM (gimp_layer_mask_get_layer (GIMP_LAYER_MASK (drawable))); else item = GIMP_ITEM (drawable); writable = ! gimp_item_is_content_locked (item); if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) writable = FALSE; } } #define SET_SENSITIVE(action,condition) \ gimp_action_group_set_action_sensitive (group, action, (condition) != 0) SET_SENSITIVE ("filters-c2g", writable && !gray); SET_SENSITIVE ("filters-cartoon", writable); SET_SENSITIVE ("filters-checkerboard", writable); SET_SENSITIVE ("filters-color-reduction", writable); SET_SENSITIVE ("filters-color-temperature", writable && !gray); SET_SENSITIVE ("filters-color-to-alpha", writable && !gray && alpha); SET_SENSITIVE ("filters-cubism", writable); SET_SENSITIVE ("filters-deinterlace", writable); SET_SENSITIVE ("filters-difference-of-gaussians", writable); SET_SENSITIVE ("filters-dot", writable); SET_SENSITIVE ("filters-dropshadow", writable && alpha); SET_SENSITIVE ("filters-edge-laplace", writable); SET_SENSITIVE ("filters-edge-sobel", writable); SET_SENSITIVE ("filters-emboss", writable); SET_SENSITIVE ("filters-exposure", writable); SET_SENSITIVE ("filters-fractal-trace", writable); SET_SENSITIVE ("filters-gaussian-blur", writable); SET_SENSITIVE ("filters-grid", writable); SET_SENSITIVE ("filters-mono-mixer", writable && !gray); SET_SENSITIVE ("filters-motion-blur-circular", writable); SET_SENSITIVE ("filters-motion-blur-linear", writable); SET_SENSITIVE ("filters-motion-blur-zoom", writable); SET_SENSITIVE ("filters-noise-cie-lch", writable); SET_SENSITIVE ("filters-noise-hsv", writable && !gray); SET_SENSITIVE ("filters-noise-hurl", writable); SET_SENSITIVE ("filters-noise-pick", writable); SET_SENSITIVE ("filters-noise-rgb", writable); SET_SENSITIVE ("filters-noise-slur", writable); SET_SENSITIVE ("filters-noise-spread", writable); SET_SENSITIVE ("filters-lens-distortion", writable); SET_SENSITIVE ("filters-photocopy", writable); SET_SENSITIVE ("filters-pixelize", writable); SET_SENSITIVE ("filters-polar-coordinates", writable); SET_SENSITIVE ("filters-red-eye-removal", writable && !gray); SET_SENSITIVE ("filters-ripple", writable); SET_SENSITIVE ("filters-semi-flatten", writable && alpha); SET_SENSITIVE ("filters-shift", writable); SET_SENSITIVE ("filters-softglow", writable); SET_SENSITIVE ("filters-threshold-alpha", writable && alpha); SET_SENSITIVE ("filters-unsharp-mask", writable); SET_SENSITIVE ("filters-vignette", writable); SET_SENSITIVE ("filters-waves", writable); SET_SENSITIVE ("filters-whirl-pinch", writable); #undef SET_SENSITIVE }
void gimp_edit_get_paste_offset (GimpImage *image, GimpDrawable *drawable, GimpObject *paste, gint viewport_x, gint viewport_y, gint viewport_width, gint viewport_height, gint *offset_x, gint *offset_y) { gint image_width; gint image_height; gint width; gint height; gboolean clamp_to_image = TRUE; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (drawable == NULL || gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (GIMP_IS_VIEWABLE (paste)); g_return_if_fail (offset_x != NULL); g_return_if_fail (offset_y != NULL); image_width = gimp_image_get_width (image); image_height = gimp_image_get_height (image); gimp_viewable_get_size (GIMP_VIEWABLE (paste), &width, &height); if (viewport_width == image_width && viewport_height == image_height) { /* if the whole image is visible, act as if there was no viewport */ viewport_x = 0; viewport_y = 0; viewport_width = 0; viewport_height = 0; } if (drawable) { /* if pasting to a drawable */ GimpContainer *children; gint off_x, off_y; gint target_x, target_y; gint target_width, target_height; gint paste_x, paste_y; gint paste_width, paste_height; gboolean have_mask; have_mask = ! gimp_channel_is_empty (gimp_image_get_mask (image)); gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); children = gimp_viewable_get_children (GIMP_VIEWABLE (drawable)); if (children && gimp_container_get_n_children (children) == 0) { /* treat empty layer groups as image-sized, use the selection * as target */ gimp_item_bounds (GIMP_ITEM (gimp_image_get_mask (image)), &target_x, &target_y, &target_width, &target_height); } else { gimp_item_mask_intersect (GIMP_ITEM (drawable), &target_x, &target_y, &target_width, &target_height); } if (! have_mask && /* if we have no mask */ viewport_width > 0 && /* and we have a viewport */ viewport_height > 0 && (width < target_width || /* and the paste is smaller than the target */ height < target_height) && /* and the viewport intersects with the target */ gimp_rectangle_intersect (viewport_x, viewport_y, viewport_width, viewport_height, off_x, off_y, /* target_x,y are 0 */ target_width, target_height, &paste_x, &paste_y, &paste_width, &paste_height)) { /* center on the viewport */ *offset_x = paste_x + (paste_width - width) / 2; *offset_y = paste_y + (paste_height- height) / 2; } else { /* otherwise center on the target */ *offset_x = off_x + target_x + (target_width - width) / 2; *offset_y = off_y + target_y + (target_height - height) / 2; /* and keep it that way */ clamp_to_image = FALSE; } } else if (viewport_width > 0 && /* if we have a viewport */ viewport_height > 0 && (width < image_width || /* and the paste is */ height < image_height)) /* smaller than the image */ { /* center on the viewport */ *offset_x = viewport_x + (viewport_width - width) / 2; *offset_y = viewport_y + (viewport_height - height) / 2; } else { /* otherwise center on the image */ *offset_x = (image_width - width) / 2; *offset_y = (image_height - height) / 2; /* and keep it that way */ clamp_to_image = FALSE; } if (clamp_to_image) { /* Ensure that the pasted layer is always within the image, if it * fits and aligned at top left if it doesn't. (See bug #142944). */ *offset_x = MIN (*offset_x, image_width - width); *offset_y = MIN (*offset_y, image_height - height); *offset_x = MAX (*offset_x, 0); *offset_y = MAX (*offset_y, 0); } }
void file_import_image (GimpImage *image, GimpContext *context, GFile *file, gboolean interactive, GimpProgress *progress) { GimpCoreConfig *config; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (G_IS_FILE (file)); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); config = image->gimp->config; if (interactive && gimp_image_get_base_type (image) != GIMP_INDEXED) { if (config->import_promote_float) { GimpPrecision old_precision = gimp_image_get_precision (image); if (old_precision != GIMP_PRECISION_FLOAT_LINEAR) { gimp_image_convert_precision (image, GIMP_PRECISION_FLOAT_LINEAR, GEGL_DITHER_NONE, GEGL_DITHER_NONE, GEGL_DITHER_NONE, progress); if (config->import_promote_dither && old_precision == GIMP_PRECISION_U8_NON_LINEAR) { gimp_image_convert_dither_u8 (image, progress); } } } if (config->import_add_alpha) { GList *layers = gimp_image_get_layer_list (image); GList *list; for (list = layers; list; list = g_list_next (list)) { if (! gimp_viewable_get_children (list->data) && ! gimp_item_is_text_layer (list->data) && ! gimp_drawable_has_alpha (list->data)) { gimp_layer_add_alpha (list->data); } } g_list_free (layers); } } gimp_image_import_color_profile (image, context, progress, interactive); /* Remember the import source */ gimp_image_set_imported_file (image, file); /* We shall treat this file as an Untitled file */ gimp_image_set_file (image, NULL); }
void edit_actions_update (GimpActionGroup *group, gpointer data) { GimpImage *image = action_data_get_image (data); GimpDisplay *display = action_data_get_display (data); GimpDrawable *drawable = NULL; gchar *undo_name = NULL; gchar *redo_name = NULL; gchar *fade_name = NULL; gboolean writable = FALSE; gboolean children = FALSE; gboolean undo_enabled = FALSE; gboolean fade_enabled = FALSE; if (image) { drawable = gimp_image_get_active_drawable (image); if (drawable) { writable = ! gimp_item_is_content_locked (GIMP_ITEM (drawable)); if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) children = TRUE; } undo_enabled = gimp_image_undo_is_enabled (image); if (undo_enabled) { GimpUndoStack *undo_stack = gimp_image_get_undo_stack (image); GimpUndoStack *redo_stack = gimp_image_get_redo_stack (image); GimpUndo *undo = gimp_undo_stack_peek (undo_stack); GimpUndo *redo = gimp_undo_stack_peek (redo_stack); const gchar *tool_undo = NULL; const gchar *tool_redo = NULL; if (display) { tool_undo = tool_manager_get_undo_desc_active (image->gimp, display); tool_redo = tool_manager_get_redo_desc_active (image->gimp, display); } if (tool_undo) undo_name = g_strdup_printf (_("_Undo %s"), tool_undo); else if (undo) undo_name = g_strdup_printf (_("_Undo %s"), gimp_object_get_name (undo)); if (tool_redo) redo_name = g_strdup_printf (_("_Redo %s"), tool_redo); else if (redo) redo_name = g_strdup_printf (_("_Redo %s"), gimp_object_get_name (redo)); undo = gimp_image_undo_get_fadeable (image); if (GIMP_IS_DRAWABLE_UNDO (undo) && GIMP_DRAWABLE_UNDO (undo)->applied_buffer) { fade_enabled = TRUE; } if (fade_enabled) { fade_name = g_strdup_printf (_("_Fade %s..."), gimp_object_get_name (undo)); } } } #define SET_LABEL(action,label) \ gimp_action_group_set_action_label (group, action, (label)) #define SET_SENSITIVE(action,condition) \ gimp_action_group_set_action_sensitive (group, action, (condition) != 0) SET_LABEL ("edit-undo", undo_name ? undo_name : _("_Undo")); SET_LABEL ("edit-redo", redo_name ? redo_name : _("_Redo")); SET_LABEL ("edit-fade", fade_name ? fade_name : _("_Fade...")); SET_SENSITIVE ("edit-undo", undo_enabled && undo_name); SET_SENSITIVE ("edit-redo", undo_enabled && redo_name); SET_SENSITIVE ("edit-strong-undo", undo_enabled && undo_name); SET_SENSITIVE ("edit-strong-redo", undo_enabled && redo_name); SET_SENSITIVE ("edit-undo-clear", undo_enabled && (undo_name || redo_name)); SET_SENSITIVE ("edit-fade", fade_enabled && fade_name); g_free (undo_name); g_free (redo_name); g_free (fade_name); SET_SENSITIVE ("edit-cut", writable && !children); SET_SENSITIVE ("edit-copy", drawable); SET_SENSITIVE ("edit-copy-visible", image); SET_SENSITIVE ("edit-paste", !image || (!drawable || (writable && !children))); SET_SENSITIVE ("edit-paste-as-new-layer", image); SET_SENSITIVE ("edit-paste-into", image && (!drawable || (writable && !children))); SET_SENSITIVE ("edit-named-cut", writable && !children); SET_SENSITIVE ("edit-named-copy", drawable); SET_SENSITIVE ("edit-named-copy-visible", drawable); SET_SENSITIVE ("edit-named-paste", TRUE); SET_SENSITIVE ("edit-clear", writable && !children); SET_SENSITIVE ("edit-fill-fg", writable && !children); SET_SENSITIVE ("edit-fill-bg", writable && !children); SET_SENSITIVE ("edit-fill-pattern", writable && !children); #undef SET_LABEL #undef SET_SENSITIVE }
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 void gimp_image_convert_profile_rgb (GimpImage *image, GimpColorProfile *src_profile, GimpColorProfile *dest_profile, GimpColorRenderingIntent intent, gboolean bpc, GimpProgress *progress) { GList *layers; GList *list; gint n_drawables; gint nth_drawable; layers = gimp_image_get_layer_list (image); n_drawables = g_list_length (layers); for (list = layers, nth_drawable = 0; list; list = g_list_next (list), nth_drawable++) { GimpDrawable *drawable = list->data; cmsHPROFILE src_lcms; cmsHPROFILE dest_lcms; const Babl *iter_format; cmsUInt32Number lcms_format; cmsUInt32Number flags; cmsHTRANSFORM transform; if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) continue; src_lcms = gimp_color_profile_get_lcms_profile (src_profile); dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile); iter_format = gimp_color_profile_get_format (gimp_drawable_get_format (drawable), &lcms_format); flags = cmsFLAGS_NOOPTIMIZE; if (bpc) flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; transform = cmsCreateTransform (src_lcms, lcms_format, dest_lcms, lcms_format, intent, flags); if (transform) { GeglBuffer *buffer; GeglBufferIterator *iter; buffer = gimp_drawable_get_buffer (drawable); gimp_drawable_push_undo (drawable, NULL, NULL, 0, 0, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer)); iter = gegl_buffer_iterator_new (buffer, NULL, 0, iter_format, GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { cmsDoTransform (transform, iter->data[0], iter->data[0], iter->length); } gimp_drawable_update (drawable, 0, 0, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer)); cmsDeleteTransform (transform); } if (progress) gimp_progress_set_value (progress, (gdouble) nth_drawable / (gdouble) n_drawables); } g_list_free (layers); }
void layers_actions_update (GimpActionGroup *group, gpointer data) { GimpImage *image = action_data_get_image (data); GimpLayer *layer = NULL; GimpLayerMask *mask = NULL; /* layer mask */ gboolean fs = FALSE; /* floating sel */ gboolean ac = FALSE; /* active channel */ gboolean sel = FALSE; gboolean alpha = FALSE; /* alpha channel present */ gboolean indexed = FALSE; /* is indexed */ gboolean lock_alpha = FALSE; gboolean can_lock_alpha = FALSE; gboolean text_layer = FALSE; gboolean writable = FALSE; gboolean children = FALSE; GList *next = NULL; GList *next_visible = NULL; GList *prev = NULL; if (image) { fs = (gimp_image_get_floating_selection (image) != NULL); ac = (gimp_image_get_active_channel (image) != NULL); sel = ! gimp_channel_is_empty (gimp_image_get_mask (image)); indexed = (gimp_image_base_type (image) == GIMP_INDEXED); layer = gimp_image_get_active_layer (image); if (layer) { GList *layer_list; GList *list; mask = gimp_layer_get_mask (layer); lock_alpha = gimp_layer_get_lock_alpha (layer); can_lock_alpha = gimp_layer_can_lock_alpha (layer); alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)); writable = ! gimp_item_is_content_locked (GIMP_ITEM (layer)); if (gimp_viewable_get_children (GIMP_VIEWABLE (layer))) children = TRUE; layer_list = gimp_item_get_container_iter (GIMP_ITEM (layer)); list = g_list_find (layer_list, layer); if (list) { prev = g_list_previous (list); next = g_list_next (list); for (next_visible = next; next_visible; next_visible = g_list_next (next_visible)) { if (gimp_item_get_visible (next_visible->data)) { /* "next_visible" is actually "next_visible" and * "writable" and "not group" */ if (gimp_item_is_content_locked (next_visible->data) || gimp_viewable_get_children (next_visible->data)) next_visible = NULL; break; } } } text_layer = gimp_item_is_text_layer (GIMP_ITEM (layer)); } } #define SET_VISIBLE(action,condition) \ gimp_action_group_set_action_visible (group, action, (condition) != 0) #define SET_SENSITIVE(action,condition) \ gimp_action_group_set_action_sensitive (group, action, (condition) != 0) #define SET_ACTIVE(action,condition) \ gimp_action_group_set_action_active (group, action, (condition) != 0) #define SET_LABEL(action,label) \ gimp_action_group_set_action_label (group, action, label) SET_VISIBLE ("layers-text-tool", text_layer && !ac); SET_SENSITIVE ("layers-edit-attributes", layer && !fs && !ac); if (layer && gimp_layer_is_floating_sel (layer)) { SET_LABEL ("layers-new", C_("layers-action", "To _New Layer")); SET_LABEL ("layers-new-last-values", C_("layers-action", "To _New Layer")); } else { SET_LABEL ("layers-new", C_("layers-action", "_New Layer...")); SET_LABEL ("layers-new-last-values", C_("layers-action", "_New Layer")); } SET_SENSITIVE ("layers-new", image); SET_SENSITIVE ("layers-new-last-values", image); SET_SENSITIVE ("layers-new-from-visible", image); SET_SENSITIVE ("layers-new-group", image && !indexed); SET_SENSITIVE ("layers-duplicate", layer && !fs && !ac); SET_SENSITIVE ("layers-delete", layer && !ac); SET_SENSITIVE ("layers-select-top", layer && !fs && !ac && prev); SET_SENSITIVE ("layers-select-bottom", layer && !fs && !ac && next); SET_SENSITIVE ("layers-select-previous", layer && !fs && !ac && prev); SET_SENSITIVE ("layers-select-next", layer && !fs && !ac && next); SET_SENSITIVE ("layers-raise", layer && !fs && !ac && prev); SET_SENSITIVE ("layers-raise-to-top", layer && !fs && !ac && prev); SET_SENSITIVE ("layers-lower", layer && !fs && !ac && next); SET_SENSITIVE ("layers-lower-to-bottom", layer && !fs && !ac && next); SET_SENSITIVE ("layers-anchor", layer && fs && !ac); SET_SENSITIVE ("layers-merge-down", layer && !fs && !ac && next_visible); SET_VISIBLE ("layers-merge-group", children); SET_SENSITIVE ("layers-merge-group", layer && !fs && !ac && children); SET_SENSITIVE ("layers-merge-layers", layer && !fs && !ac); SET_SENSITIVE ("layers-flatten-image", layer && !fs && !ac); SET_VISIBLE ("layers-text-discard", text_layer && !ac); SET_VISIBLE ("layers-text-to-vectors", text_layer && !ac); SET_VISIBLE ("layers-text-along-vectors", text_layer && !ac); SET_SENSITIVE ("layers-resize", writable && !ac); SET_SENSITIVE ("layers-resize-to-image", writable && !ac); SET_SENSITIVE ("layers-scale", writable && !ac); SET_SENSITIVE ("layers-crop", writable && sel); SET_SENSITIVE ("layers-alpha-add", writable && !children && !fs && !alpha); SET_SENSITIVE ("layers-alpha-remove", writable && !children && !fs && alpha); SET_SENSITIVE ("layers-lock-alpha", can_lock_alpha); SET_ACTIVE ("layers-lock-alpha", lock_alpha); SET_SENSITIVE ("layers-mask-add", layer && !fs && !ac && !mask && !children); SET_SENSITIVE ("layers-mask-apply", writable && !fs && !ac && mask && !children); SET_SENSITIVE ("layers-mask-delete", layer && !fs && !ac && mask); SET_SENSITIVE ("layers-mask-edit", layer && !fs && !ac && mask); SET_SENSITIVE ("layers-mask-show", layer && !fs && !ac && mask); SET_SENSITIVE ("layers-mask-disable", layer && !fs && !ac && mask); SET_ACTIVE ("layers-mask-edit", mask && gimp_layer_mask_get_edit (mask)); SET_ACTIVE ("layers-mask-show", mask && gimp_layer_mask_get_show (mask)); SET_ACTIVE ("layers-mask-disable", mask && !gimp_layer_mask_get_apply (mask)); SET_SENSITIVE ("layers-mask-selection-replace", layer && !fs && !ac && mask); SET_SENSITIVE ("layers-mask-selection-add", layer && !fs && !ac && mask); SET_SENSITIVE ("layers-mask-selection-subtract", layer && !fs && !ac && mask); SET_SENSITIVE ("layers-mask-selection-intersect", layer && !fs && !ac && mask); SET_SENSITIVE ("layers-alpha-selection-replace", layer && !fs && !ac); SET_SENSITIVE ("layers-alpha-selection-add", layer && !fs && !ac); SET_SENSITIVE ("layers-alpha-selection-subtract", layer && !fs && !ac); SET_SENSITIVE ("layers-alpha-selection-intersect", layer && !fs && !ac); #undef SET_VISIBLE #undef SET_SENSITIVE #undef SET_ACTIVE #undef SET_LABEL }