예제 #1
0
static GValueArray *
floating_sel_attach_invoker (GimpProcedure      *procedure,
                             Gimp               *gimp,
                             GimpContext        *context,
                             GimpProgress       *progress,
                             const GValueArray  *args,
                             GError            **error)
{
  gboolean success = TRUE;
  GimpLayer *layer;
  GimpDrawable *drawable;

  layer = gimp_value_get_layer (&args->values[0], gimp);
  drawable = gimp_value_get_drawable (&args->values[1], gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        floating_sel_attach (layer, drawable);
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}
예제 #2
0
static GValueArray *
drawable_parasite_list_invoker (GimpProcedure      *procedure,
                                Gimp               *gimp,
                                GimpContext        *context,
                                GimpProgress       *progress,
                                const GValueArray  *args,
                                GError            **error)
{
  gboolean success = TRUE;
  GValueArray *return_vals;
  GimpDrawable *drawable;
  gint32 num_parasites = 0;
  gchar **parasites = NULL;

  drawable = gimp_value_get_drawable (&args->values[0], gimp);

  if (success)
    {
      parasites = gimp_item_parasite_list (GIMP_ITEM (drawable), &num_parasites);
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    {
      g_value_set_int (&return_vals->values[1], num_parasites);
      gimp_value_take_stringarray (&return_vals->values[2], parasites, num_parasites);
    }

  return return_vals;
}
예제 #3
0
static GValueArray *
drawable_parasite_find_invoker (GimpProcedure      *procedure,
                                Gimp               *gimp,
                                GimpContext        *context,
                                GimpProgress       *progress,
                                const GValueArray  *args,
                                GError            **error)
{
  gboolean success = TRUE;
  GValueArray *return_vals;
  GimpDrawable *drawable;
  const gchar *name;
  GimpParasite *parasite = NULL;

  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  name = g_value_get_string (&args->values[1]);

  if (success)
    {
      parasite = gimp_parasite_copy (gimp_item_parasite_find (GIMP_ITEM (drawable),
                                                              name));

      if (! parasite)
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_take_boxed (&return_vals->values[1], parasite);

  return return_vals;
}
예제 #4
0
static GimpValueArray *
text_fontname_invoker (GimpProcedure         *procedure,
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  GimpImage *image;
  GimpDrawable *drawable;
  gdouble x;
  gdouble y;
  const gchar *text;
  gint32 border;
  gboolean antialias;
  gdouble size;
  const gchar *fontname;
  GimpLayer *text_layer = NULL;

  image = gimp_value_get_image (gimp_value_array_index (args, 0), gimp);
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 1), gimp);
  x = g_value_get_double (gimp_value_array_index (args, 2));
  y = g_value_get_double (gimp_value_array_index (args, 3));
  text = g_value_get_string (gimp_value_array_index (args, 4));
  border = g_value_get_int (gimp_value_array_index (args, 5));
  antialias = g_value_get_boolean (gimp_value_array_index (args, 6));
  size = g_value_get_double (gimp_value_array_index (args, 7));
  fontname = g_value_get_string (gimp_value_array_index (args, 9));

  if (success)
    {
      if (drawable &&
          (! gimp_pdb_item_is_attached (GIMP_ITEM (drawable), image,
                                        GIMP_PDB_ITEM_CONTENT, error) ||
           ! gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error)))
        success = FALSE;

      if (success)
        {
          gchar *real_fontname = g_strdup_printf ("%s %d", fontname, (gint) size);

          text_layer = text_render (image, drawable, context,
                                    x, y, real_fontname, text,
                                    border, antialias);

          g_free (real_fontname);
        }
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    gimp_value_set_layer (gimp_value_array_index (return_vals, 1), text_layer);

  return return_vals;
}
예제 #5
0
static GValueArray *
text_fontname_invoker (GimpProcedure     *procedure,
                       Gimp              *gimp,
                       GimpContext       *context,
                       GimpProgress      *progress,
                       const GValueArray *args)
{
  gboolean success = TRUE;
  GValueArray *return_vals;
  GimpImage *image;
  GimpDrawable *drawable;
  gdouble x;
  gdouble y;
  const gchar *text;
  gint32 border;
  gboolean antialias;
  gdouble size;
  gint32 size_type;
  const gchar *fontname;
  GimpLayer *text_layer = NULL;

  image = gimp_value_get_image (&args->values[0], gimp);
  drawable = gimp_value_get_drawable (&args->values[1], gimp);
  x = g_value_get_double (&args->values[2]);
  y = g_value_get_double (&args->values[3]);
  text = g_value_get_string (&args->values[4]);
  border = g_value_get_int (&args->values[5]);
  antialias = g_value_get_boolean (&args->values[6]);
  size = g_value_get_double (&args->values[7]);
  size_type = g_value_get_enum (&args->values[8]);
  fontname = g_value_get_string (&args->values[9]);

  if (success)
    {
      if (drawable && ! gimp_item_is_attached (GIMP_ITEM (drawable)))
        success = FALSE;

      if (success)
        {
          gchar *real_fontname = g_strdup_printf ("%s %d", fontname, (gint) size);

          text_layer = text_render (image, drawable, context,
                                    x, y, real_fontname, text,
                                    border, antialias);

          g_free (real_fontname);
        }
    }

  return_vals = gimp_procedure_get_return_values (procedure, success);

  if (success)
    gimp_value_set_layer (&return_vals->values[1], text_layer);

  return return_vals;
}
예제 #6
0
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;
}
예제 #7
0
파일: edit-cmds.c 프로젝트: jiapei100/gimp
static GimpValueArray *
edit_named_cut_invoker (GimpProcedure         *procedure,
                        Gimp                  *gimp,
                        GimpContext           *context,
                        GimpProgress          *progress,
                        const GimpValueArray  *args,
                        GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  GimpDrawable *drawable;
  const gchar *buffer_name;
  gchar *real_name = NULL;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  buffer_name = g_value_get_string (gimp_value_array_index (args, 1));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GimpImage *image    = gimp_item_get_image (GIMP_ITEM (drawable));
          GError    *my_error = NULL;

          real_name = (gchar *) gimp_edit_named_cut (image, buffer_name,
                                                     drawable, context, &my_error);

          if (real_name)
            {
              real_name = g_strdup (real_name);
            }
          else
            {
              gimp_message_literal (gimp,
                                    G_OBJECT (progress), GIMP_MESSAGE_WARNING,
                                    my_error->message);
              g_clear_error (&my_error);
            }
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_take_string (gimp_value_array_index (return_vals, 1), real_name);

  return return_vals;
}
예제 #8
0
static GimpValueArray *
image_select_contiguous_color_invoker (GimpProcedure         *procedure,
                                       Gimp                  *gimp,
                                       GimpContext           *context,
                                       GimpProgress          *progress,
                                       const GimpValueArray  *args,
                                       GError               **error)
{
  gboolean success = TRUE;
  GimpImage *image;
  gint32 operation;
  GimpDrawable *drawable;
  gdouble x;
  gdouble y;

  image = gimp_value_get_image (gimp_value_array_index (args, 0), gimp);
  operation = g_value_get_enum (gimp_value_array_index (args, 1));
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  x = g_value_get_double (gimp_value_array_index (args, 3));
  y = g_value_get_double (gimp_value_array_index (args, 4));

  if (success)
    {
      GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);

      if (pdb_context->sample_merged ||
          gimp_pdb_item_is_attached (GIMP_ITEM (drawable), image, 0, error))
        {

          gimp_channel_select_fuzzy (gimp_image_get_mask (image),
                                     drawable,
                                     pdb_context->sample_merged,
                                     x, y,
                                     pdb_context->sample_threshold,
                                     pdb_context->sample_transparent,
                                     pdb_context->sample_criterion,
                                     pdb_context->diagonal_neighbors,
                                     operation,
                                     pdb_context->antialias,
                                     pdb_context->feather,
                                     pdb_context->feather_radius_x,
                                     pdb_context->feather_radius_y);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}
예제 #9
0
파일: edit-cmds.c 프로젝트: jiapei100/gimp
static GimpValueArray *
edit_named_paste_invoker (GimpProcedure         *procedure,
                          Gimp                  *gimp,
                          GimpContext           *context,
                          GimpProgress          *progress,
                          const GimpValueArray  *args,
                          GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  GimpDrawable *drawable;
  const gchar *buffer_name;
  gboolean paste_into;
  GimpLayer *floating_sel = NULL;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  buffer_name = g_value_get_string (gimp_value_array_index (args, 1));
  paste_into = g_value_get_boolean (gimp_value_array_index (args, 2));

  if (success)
    {
      GimpBuffer *buffer = gimp_pdb_get_buffer (gimp, buffer_name, error);

      if (buffer &&
          gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          floating_sel = gimp_edit_paste (gimp_item_get_image (GIMP_ITEM (drawable)),
                                          drawable, GIMP_OBJECT (buffer),
                                          paste_into ?
                                          GIMP_PASTE_TYPE_FLOATING_INTO :
                                          GIMP_PASTE_TYPE_FLOATING,
                                          -1, -1, -1, -1);
          if (! floating_sel)
            success = FALSE;
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    gimp_value_set_layer (gimp_value_array_index (return_vals, 1), floating_sel);

  return return_vals;
}
예제 #10
0
파일: edit-cmds.c 프로젝트: jiapei100/gimp
static GimpValueArray *
edit_cut_invoker (GimpProcedure         *procedure,
                  Gimp                  *gimp,
                  GimpContext           *context,
                  GimpProgress          *progress,
                  const GimpValueArray  *args,
                  GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  GimpDrawable *drawable;
  gboolean non_empty = FALSE;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GimpImage *image    = gimp_item_get_image (GIMP_ITEM (drawable));
          GError    *my_error = NULL;

          non_empty = gimp_edit_cut (image, drawable, context, &my_error) != NULL;

          if (! non_empty)
            {
              gimp_message_literal (gimp,
                                    G_OBJECT (progress), GIMP_MESSAGE_WARNING,
                                    my_error->message);
              g_clear_error (&my_error);
            }
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_boolean (gimp_value_array_index (return_vals, 1), non_empty);

  return return_vals;
}
예제 #11
0
static GimpValueArray *
selection_float_invoker (GimpProcedure         *procedure,
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  GimpDrawable *drawable;
  gint32 offx;
  gint32 offy;
  GimpLayer *layer = NULL;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  offx = g_value_get_int (gimp_value_array_index (args, 1));
  offy = g_value_get_int (gimp_value_array_index (args, 2));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));

          layer = gimp_selection_float (GIMP_SELECTION (gimp_image_get_mask (image)),
                                        drawable, context, TRUE, offx, offy,
                                        error);
          if (! layer)
            success = FALSE;
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    gimp_value_set_layer (gimp_value_array_index (return_vals, 1), layer);

  return return_vals;
}
예제 #12
0
static GValueArray *
image_select_color_invoker (GimpProcedure      *procedure,
                            Gimp               *gimp,
                            GimpContext        *context,
                            GimpProgress       *progress,
                            const GValueArray  *args,
                            GError            **error)
{
  gboolean success = TRUE;
  GimpImage *image;
  gint32 operation;
  GimpDrawable *drawable;
  GimpRGB color;

  image = gimp_value_get_image (&args->values[0], gimp);
  operation = g_value_get_enum (&args->values[1]);
  drawable = gimp_value_get_drawable (&args->values[2], gimp);
  gimp_value_get_rgb (&args->values[3], &color);

  if (success)
    {
      GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);

      if (pdb_context->sample_merged ||
          gimp_pdb_item_is_attached (GIMP_ITEM (drawable), image, FALSE, error))
        {
          gimp_channel_select_by_color (gimp_image_get_mask (image), drawable,
                                        pdb_context->sample_merged,
                                        &color,
                                        (gint) (pdb_context->sample_threshold * 255.99),
                                        pdb_context->sample_transparent,
                                        pdb_context->sample_criterion,
                                        operation,
                                        pdb_context->antialias,
                                        pdb_context->feather,
                                        pdb_context->feather_radius_x,
                                        pdb_context->feather_radius_y);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}
예제 #13
0
static GValueArray *
selection_float_invoker (GimpProcedure      *procedure,
                         Gimp               *gimp,
                         GimpContext        *context,
                         GimpProgress       *progress,
                         const GValueArray  *args,
                         GError            **error)
{
  gboolean success = TRUE;
  GValueArray *return_vals;
  GimpDrawable *drawable;
  gint32 offx;
  gint32 offy;
  GimpLayer *layer = NULL;

  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  offx = g_value_get_int (&args->values[1]);
  offy = g_value_get_int (&args->values[2]);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), error))
        {
          GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));

          layer = gimp_selection_float (gimp_image_get_mask (image),
                                        drawable, context, TRUE, offx, offy,
                                        error);
          if (! layer)
            success = FALSE;
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    gimp_value_set_layer (&return_vals->values[1], layer);

  return return_vals;
}
예제 #14
0
static GValueArray *
drawable_parasite_detach_invoker (GimpProcedure      *procedure,
                                  Gimp               *gimp,
                                  GimpContext        *context,
                                  GimpProgress       *progress,
                                  const GValueArray  *args,
                                  GError            **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  const gchar *name;

  drawable = gimp_value_get_drawable (&args->values[0], gimp);
  name = g_value_get_string (&args->values[1]);

  if (success)
    {
      gimp_item_parasite_detach (GIMP_ITEM (drawable), name);
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}
예제 #15
0
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;
}
예제 #16
0
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;
}