void gimp_image_item_list_transform (GimpImage *image, GList *list, GimpContext *context, const GimpMatrix3 *matrix, GimpTransformDirection direction, GimpInterpolationType interpolation_type, GimpTransformResize clip_result, GimpProgress *progress) { 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)); if (list) { GList *l; if (list->next) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, C_("undo-type", "Transform Items")); for (l = list; l; l = g_list_next (l)) gimp_item_transform (GIMP_ITEM (l->data), context, matrix, direction, interpolation_type, clip_result, progress); if (list->next) gimp_image_undo_group_end (image); } }
void gimp_image_item_list_transform (GimpImage *image, GList *list, GimpContext *context, const GimpMatrix3 *matrix, GimpTransformDirection direction, GimpInterpolationType interpolation_type, GimpTransformResize clip_result, GimpProgress *progress) { 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)); if (list) { GimpObjectQueue *queue = NULL; GList *l; if (progress) { queue = gimp_object_queue_new (progress); progress = GIMP_PROGRESS (queue); gimp_object_queue_push_list (queue, list); } if (list->next) { gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, C_("undo-type", "Transform Items")); for (l = list; l; l = g_list_next (l)) gimp_item_start_transform (GIMP_ITEM (l->data), TRUE); } for (l = list; l; l = g_list_next (l)) { if (queue) gimp_object_queue_pop (queue); gimp_item_transform (GIMP_ITEM (l->data), context, matrix, direction, interpolation_type, clip_result, progress); } if (list->next) { for (l = list; l; l = g_list_next (l)) gimp_item_end_transform (GIMP_ITEM (l->data), TRUE); gimp_image_undo_group_end (image); } g_clear_object (&queue); } }
GimpDrawable * gimp_drawable_transform_affine (GimpDrawable *drawable, GimpContext *context, const GimpMatrix3 *matrix, GimpTransformDirection direction, GimpInterpolationType interpolation_type, gint recursion_level, GimpTransformResize clip_result, GimpProgress *progress) { 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); g_return_val_if_fail (matrix != NULL, NULL); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), 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", "Transform")); /* 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; 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 = GIMP_TRANSFORM_RESIZE_CLIP; /* 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_transform (GIMP_ITEM (mask), context, matrix, direction, interpolation_type, recursion_level, clip_result, progress); } /* transform the buffer */ new_buffer = gimp_drawable_transform_buffer_affine (drawable, context, orig_buffer, orig_offset_x, orig_offset_y, matrix, direction, interpolation_type, recursion_level, clip_result, &new_offset_x, &new_offset_y, progress); /* 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 GimpValueArray * transform_2d_invoker (GimpProcedure *procedure, Gimp *gimp, GimpContext *context, GimpProgress *progress, const GimpValueArray *args, GError **error) { gboolean success = TRUE; GimpValueArray *return_vals; GimpDrawable *drawable; gboolean interpolation; gdouble source_x; gdouble source_y; gdouble scale_x; gdouble scale_y; gdouble angle; gdouble dest_x; gdouble dest_y; drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp); interpolation = g_value_get_boolean (gimp_value_array_index (args, 1)); source_x = g_value_get_double (gimp_value_array_index (args, 2)); source_y = g_value_get_double (gimp_value_array_index (args, 3)); scale_x = g_value_get_double (gimp_value_array_index (args, 4)); scale_y = g_value_get_double (gimp_value_array_index (args, 5)); angle = g_value_get_double (gimp_value_array_index (args, 6)); dest_x = g_value_get_double (gimp_value_array_index (args, 7)); dest_y = g_value_get_double (gimp_value_array_index (args, 8)); 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)) { GimpMatrix3 matrix; GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE; /* Assemble the transformation matrix */ gimp_matrix3_identity (&matrix); gimp_matrix3_translate (&matrix, -source_x, -source_y); gimp_matrix3_scale (&matrix, scale_x, scale_y); gimp_matrix3_rotate (&matrix, angle); gimp_matrix3_translate (&matrix, dest_x, dest_y); if (interpolation) interpolation_type = gimp->config->interpolation_type; if (progress) gimp_progress_start (progress, _("2D Transform"), FALSE); 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_affine (drawable, context, &matrix, GIMP_TRANSFORM_FORWARD, interpolation_type, 3, FALSE, progress)) { success = FALSE; } } else { gimp_item_transform (GIMP_ITEM (drawable), context, &matrix, GIMP_TRANSFORM_FORWARD, interpolation, 3, FALSE, progress); } if (progress) gimp_progress_end (progress); } } 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; }
static GimpValueArray * shear_invoker (GimpProcedure *procedure, Gimp *gimp, GimpContext *context, GimpProgress *progress, const GimpValueArray *args, GError **error) { gboolean success = TRUE; GimpValueArray *return_vals; GimpDrawable *drawable; gboolean interpolation; gint32 shear_type; gdouble magnitude; drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp); interpolation = g_value_get_boolean (gimp_value_array_index (args, 1)); shear_type = g_value_get_enum (gimp_value_array_index (args, 2)); magnitude = g_value_get_double (gimp_value_array_index (args, 3)); 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)) { GimpMatrix3 matrix; GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE; gint off_x, off_y; gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); x += off_x; y += off_y; /* Assemble the transformation matrix */ gimp_matrix3_identity (&matrix); gimp_transform_matrix_shear (&matrix, x, y, width, height, shear_type, magnitude); if (interpolation) interpolation_type = gimp->config->interpolation_type; if (progress) gimp_progress_start (progress, _("Shearing"), FALSE); 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_affine (drawable, context, &matrix, GIMP_TRANSFORM_FORWARD, interpolation_type, 3, FALSE, progress)) { success = FALSE; } } else { gimp_item_transform (GIMP_ITEM (drawable), context, &matrix, GIMP_TRANSFORM_FORWARD, interpolation, 3, FALSE, progress); } if (progress) gimp_progress_end (progress); } } 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; }