void gimp_image_item_list_flip (GimpImage *image, GList *list, GimpContext *context, GimpOrientationType flip_type, gdouble axis, gboolean clip_result) { g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); if (list) { GList *l; if (list->next) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, C_("undo-type", "Flip Items")); for (l = list; l; l = g_list_next (l)) gimp_item_flip (GIMP_ITEM (l->data), context, flip_type, axis, clip_result); if (list->next) gimp_image_undo_group_end (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 drawable_flip_cmd_callback (GtkAction *action, gint value, gpointer data) { GimpImage *image; GimpDrawable *drawable; GimpItem *item; GimpContext *context; gint off_x, off_y; gdouble axis = 0.0; return_if_no_drawable (image, drawable, data); return_if_no_context (context, data); item = GIMP_ITEM (drawable); gimp_item_get_offset (item, &off_x, &off_y); switch ((GimpOrientationType) value) { case GIMP_ORIENTATION_HORIZONTAL: axis = ((gdouble) off_x + (gdouble) gimp_item_get_width (item) / 2.0); break; case GIMP_ORIENTATION_VERTICAL: axis = ((gdouble) off_y + (gdouble) gimp_item_get_height (item) / 2.0); break; default: break; } if (gimp_item_get_linked (item)) { gimp_item_linked_flip (item, context, (GimpOrientationType) value, axis, FALSE); } else { gimp_item_flip (item, context, (GimpOrientationType) value, axis, FALSE); } gimp_image_flush (image); }
void gimp_text_layer_flip (GimpItem *item, GimpContext *context, GimpOrientationType flip_type, gdouble axis, gboolean clip_result) { GimpTextLayer *layer = GIMP_TEXT_LAYER (item); if (gimp_text_layer_transform_flip (layer, flip_type, axis)) { GimpLayerMask *mask = gimp_layer_get_mask (GIMP_LAYER (layer)); if (mask) gimp_item_flip (GIMP_ITEM (mask), context, flip_type, axis, clip_result); } else { gimp_text_layer_parent_class ()->flip (item, context, flip_type, axis, clip_result); } }
GimpDrawable * gimp_drawable_transform_flip (GimpDrawable *drawable, GimpContext *context, GimpOrientationType flip_type, gdouble axis, gboolean clip_result) { GimpImage *image; GeglBuffer *orig_buffer; gint orig_offset_x; gint orig_offset_y; gboolean new_layer; GimpDrawable *result = NULL; g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL); g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); image = gimp_item_get_image (GIMP_ITEM (drawable)); /* Start a transform undo group */ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, C_("undo-type", "Flip")); /* Cut/Copy from the specified drawable */ orig_buffer = gimp_drawable_transform_cut (drawable, context, &orig_offset_x, &orig_offset_y, &new_layer); if (orig_buffer) { GeglBuffer *new_buffer = NULL; gint new_offset_x; gint new_offset_y; /* always clip unfloated buffers so they keep their size */ if (GIMP_IS_CHANNEL (drawable) && ! babl_format_has_alpha (gegl_buffer_get_format (orig_buffer))) clip_result = TRUE; /* also transform the mask if we are transforming an entire layer */ if (GIMP_IS_LAYER (drawable) && gimp_layer_get_mask (GIMP_LAYER (drawable)) && gimp_channel_is_empty (gimp_image_get_mask (image))) { GimpLayerMask *mask = gimp_layer_get_mask (GIMP_LAYER (drawable)); gimp_item_flip (GIMP_ITEM (mask), context, flip_type, axis, clip_result); } /* transform the buffer */ if (orig_buffer) { new_buffer = gimp_drawable_transform_buffer_flip (drawable, context, orig_buffer, orig_offset_x, orig_offset_y, flip_type, axis, clip_result, &new_offset_x, &new_offset_y); /* Free the cut/copied buffer */ g_object_unref (orig_buffer); } if (new_buffer) { result = gimp_drawable_transform_paste (drawable, new_buffer, new_offset_x, new_offset_y, new_layer); g_object_unref (new_buffer); } } /* push the undo group end */ gimp_image_undo_group_end (image); return result; }
static GeglBuffer * gimp_flip_tool_transform (GimpTransformTool *tr_tool, GimpItem *active_item, GeglBuffer *orig_buffer, gint orig_offset_x, gint orig_offset_y, GimpColorProfile **buffer_profile, gint *new_offset_x, gint *new_offset_y) { GimpFlipTool *flip = GIMP_FLIP_TOOL (tr_tool); GimpFlipOptions *options = GIMP_FLIP_TOOL_GET_OPTIONS (tr_tool); GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); GimpContext *context = GIMP_CONTEXT (options); GimpOrientationType flip_type = GIMP_ORIENTATION_UNKNOWN; gdouble axis = 0.0; gboolean clip_result = FALSE; GeglBuffer *ret = NULL; flip_type = gimp_flip_tool_get_flip_type (flip); if (flip->guide) { axis = gimp_guide_get_position (flip->guide); } else { switch (flip_type) { case GIMP_ORIENTATION_HORIZONTAL: axis = ((gdouble) tr_tool->x1 + (gdouble) (tr_tool->x2 - tr_tool->x1) / 2.0); break; case GIMP_ORIENTATION_VERTICAL: axis = ((gdouble) tr_tool->y1 + (gdouble) (tr_tool->y2 - tr_tool->y1) / 2.0); break; default: break; } } switch (tr_options->clip) { case GIMP_TRANSFORM_RESIZE_ADJUST: clip_result = FALSE; break; case GIMP_TRANSFORM_RESIZE_CLIP: clip_result = TRUE; break; default: g_return_val_if_reached (NULL); } if (orig_buffer) { /* this happens when transforming a selection cut out of a * normal drawable, or the selection */ /* always clip the selection and unfloated channels * so they keep their size */ if (GIMP_IS_CHANNEL (active_item) && ! babl_format_has_alpha (gegl_buffer_get_format (orig_buffer))) clip_result = TRUE; ret = gimp_drawable_transform_buffer_flip (GIMP_DRAWABLE (active_item), context, orig_buffer, orig_offset_x, orig_offset_y, flip_type, axis, clip_result, buffer_profile, new_offset_x, new_offset_y); } else { /* this happens for entire drawables, paths and layer groups */ /* always clip layer masks so they keep their size */ if (GIMP_IS_CHANNEL (active_item)) clip_result = TRUE; if (gimp_item_get_linked (active_item)) { gimp_item_linked_flip (active_item, context, flip_type, axis, clip_result); } else { gimp_item_flip (active_item, context, flip_type, axis, clip_result); } } return ret; }
void gimp_image_flip (GimpImage *image, GimpContext *context, GimpOrientationType flip_type, GimpProgress *progress) { GList *list; gdouble axis; gdouble progress_max; gdouble progress_current = 1.0; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); gimp_set_busy (image->gimp); switch (flip_type) { case GIMP_ORIENTATION_HORIZONTAL: axis = (gdouble) gimp_image_get_width (image) / 2.0; break; case GIMP_ORIENTATION_VERTICAL: axis = (gdouble) gimp_image_get_height (image) / 2.0; break; default: g_warning ("%s: unknown flip_type", G_STRFUNC); return; } progress_max = (image->channels->num_children + image->layers->num_children + image->vectors->num_children + 1 /* selection */); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_FLIP, NULL); /* Flip all channels */ for (list = GIMP_LIST (image->channels)->list; list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_flip (item, context, flip_type, axis, TRUE); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Flip all vectors */ for (list = GIMP_LIST (image->vectors)->list; list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_flip (item, context, flip_type, axis, FALSE); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Don't forget the selection mask! */ gimp_item_flip (GIMP_ITEM (gimp_image_get_mask (image)), context, flip_type, axis, TRUE); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); /* Flip all layers */ for (list = GIMP_LIST (image->layers)->list; list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_flip (item, context, flip_type, axis, FALSE); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Flip all Guides */ for (list = gimp_image_get_guides (image); list; list = g_list_next (list)) { GimpGuide *guide = list->data; gint position = gimp_guide_get_position (guide); switch (gimp_guide_get_orientation (guide)) { case GIMP_ORIENTATION_HORIZONTAL: if (flip_type == GIMP_ORIENTATION_VERTICAL) gimp_image_move_guide (image, guide, gimp_image_get_height (image) - position, TRUE); break; case GIMP_ORIENTATION_VERTICAL: if (flip_type == GIMP_ORIENTATION_HORIZONTAL) gimp_image_move_guide (image, guide, gimp_image_get_width (image) - position, TRUE); break; default: break; } } /* Flip all sample points */ for (list = gimp_image_get_sample_points (image); list; list = g_list_next (list)) { GimpSamplePoint *sample_point = list->data; if (flip_type == GIMP_ORIENTATION_VERTICAL) gimp_image_move_sample_point (image, sample_point, sample_point->x, gimp_image_get_height (image) - sample_point->y, TRUE); if (flip_type == GIMP_ORIENTATION_HORIZONTAL) gimp_image_move_sample_point (image, sample_point, gimp_image_get_width (image) - sample_point->x, sample_point->y, TRUE); } gimp_image_undo_group_end (image); gimp_unset_busy (image->gimp); }
static TileManager * gimp_flip_tool_transform (GimpTransformTool *trans_tool, GimpItem *active_item, gboolean mask_empty, GimpDisplay *display) { GimpFlipOptions *options = GIMP_FLIP_TOOL_GET_OPTIONS (trans_tool); GimpTransformOptions *tr_options = GIMP_TRANSFORM_OPTIONS (options); GimpContext *context = GIMP_CONTEXT (options); gdouble axis = 0.0; TileManager *ret = NULL; switch (options->flip_type) { case GIMP_ORIENTATION_HORIZONTAL: axis = ((gdouble) trans_tool->x1 + (gdouble) (trans_tool->x2 - trans_tool->x1) / 2.0); break; case GIMP_ORIENTATION_VERTICAL: axis = ((gdouble) trans_tool->y1 + (gdouble) (trans_tool->y2 - trans_tool->y1) / 2.0); break; default: break; } if (gimp_item_get_linked (active_item)) gimp_item_linked_flip (active_item, context, options->flip_type, axis, FALSE); if (GIMP_IS_LAYER (active_item) && gimp_layer_get_mask (GIMP_LAYER (active_item)) && mask_empty) { GimpLayerMask *mask = gimp_layer_get_mask (GIMP_LAYER (active_item)); gimp_item_flip (GIMP_ITEM (mask), context, options->flip_type, axis, FALSE); } switch (tr_options->type) { case GIMP_TRANSFORM_TYPE_LAYER: case GIMP_TRANSFORM_TYPE_SELECTION: if (trans_tool->original) ret = gimp_drawable_transform_tiles_flip (GIMP_DRAWABLE (active_item), context, trans_tool->original, options->flip_type, axis, FALSE); break; case GIMP_TRANSFORM_TYPE_PATH: gimp_item_flip (active_item, context, options->flip_type, axis, FALSE); break; } return ret; }