Пример #1
0
static void
gimp_vectors_mod_undo_pop (GimpUndo            *undo,
                           GimpUndoMode         undo_mode,
                           GimpUndoAccumulator *accum)
{
  GimpVectorsModUndo *vectors_mod_undo = GIMP_VECTORS_MOD_UNDO (undo);
  GimpVectors        *vectors          = GIMP_VECTORS (GIMP_ITEM_UNDO (undo)->item);
  GimpVectors        *temp;

  GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);

  temp = vectors_mod_undo->vectors;

  vectors_mod_undo->vectors =
    GIMP_VECTORS (gimp_item_duplicate (GIMP_ITEM (vectors),
                                       G_TYPE_FROM_INSTANCE (vectors),
                                       FALSE));

  gimp_vectors_freeze (vectors);

  gimp_vectors_copy_strokes (temp, vectors);

  GIMP_ITEM (vectors)->width    = GIMP_ITEM (temp)->width;
  GIMP_ITEM (vectors)->height   = GIMP_ITEM (temp)->height;
  GIMP_ITEM (vectors)->offset_x = GIMP_ITEM (temp)->offset_x;
  GIMP_ITEM (vectors)->offset_y = GIMP_ITEM (temp)->offset_y;

  g_object_unref (temp);

  gimp_vectors_thaw (vectors);
}
Пример #2
0
static void
gimp_vectors_transform (GimpItem               *item,
                        GimpContext            *context,
                        const GimpMatrix3      *matrix,
                        GimpTransformDirection  direction,
                        GimpInterpolationType   interpolation_type,
                        GimpTransformResize     clip_result,
                        GimpProgress           *progress)
{
  GimpVectors *vectors = GIMP_VECTORS (item);
  GimpMatrix3  local_matrix;
  GList       *list;

  gimp_vectors_freeze (vectors);

  gimp_image_undo_push_vectors_mod (gimp_item_get_image (item),
                                    _("Transform Path"),
                                    vectors);

  local_matrix = *matrix;

  if (direction == GIMP_TRANSFORM_BACKWARD)
    gimp_matrix3_invert (&local_matrix);

  for (list = vectors->strokes; list; list = g_list_next (list))
    {
      GimpStroke *stroke = list->data;

      gimp_stroke_transform (stroke, &local_matrix);
    }

  gimp_vectors_thaw (vectors);
}
Пример #3
0
static void
gimp_vectors_rotate (GimpItem         *item,
                     GimpContext      *context,
                     GimpRotationType  rotate_type,
                     gdouble           center_x,
                     gdouble           center_y,
                     gboolean          clip_result)
{
  GimpVectors *vectors = GIMP_VECTORS (item);
  GList       *list;
  GimpMatrix3  matrix;

  gimp_matrix3_identity (&matrix);
  gimp_transform_matrix_rotate (&matrix, rotate_type, center_x, center_y);

  gimp_vectors_freeze (vectors);

  gimp_image_undo_push_vectors_mod (gimp_item_get_image (item),
                                    _("Rotate Path"),
                                    vectors);

  for (list = vectors->strokes; list; list = g_list_next (list))
    {
      GimpStroke *stroke = list->data;

      gimp_stroke_transform (stroke, &matrix);
    }

  gimp_vectors_thaw (vectors);
}
Пример #4
0
static void
gimp_vectors_resize (GimpItem    *item,
                     GimpContext *context,
                     gint         new_width,
                     gint         new_height,
                     gint         offset_x,
                     gint         offset_y)
{
  GimpVectors *vectors = GIMP_VECTORS (item);
  GimpImage   *image   = gimp_item_get_image (item);
  GList       *list;

  gimp_vectors_freeze (vectors);

  if (gimp_item_is_attached (item))
    gimp_image_undo_push_vectors_mod (image, NULL, vectors);

  for (list = vectors->strokes; list; list = g_list_next (list))
    {
      GimpStroke *stroke = list->data;

      gimp_stroke_translate (stroke, offset_x, offset_y);
    }

  GIMP_ITEM_CLASS (parent_class)->resize (item, context,
                                          gimp_image_get_width  (image),
                                          gimp_image_get_height (image),
                                          0, 0);

  gimp_vectors_thaw (vectors);
}
Пример #5
0
GimpVectors *
gimp_vectors_get_parent (GimpVectors *vectors)
{
  g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);

  return GIMP_VECTORS (gimp_viewable_get_parent (GIMP_VIEWABLE (vectors)));
}
Пример #6
0
static void
gimp_vectors_translate (GimpItem *item,
                        gint      offset_x,
                        gint      offset_y,
                        gboolean  push_undo)
{
  GimpVectors *vectors = GIMP_VECTORS (item);
  GList       *list;

  gimp_vectors_freeze (vectors);

  if (push_undo)
    gimp_image_undo_push_vectors_mod (gimp_item_get_image (item),
                                      _("Move Path"),
                                      vectors);

  for (list = vectors->strokes; list; list = g_list_next (list))
    {
      GimpStroke *stroke = list->data;

      gimp_stroke_translate (stroke, offset_x, offset_y);
    }

  gimp_vectors_thaw (vectors);
}
Пример #7
0
static GimpVectors *
gimp_image_duplicate_vectors (GimpImage *image,
                              GimpImage *new_image)
{
  GimpVectors *active_vectors = NULL;
  GList       *list;
  gint         count;

  for (list = gimp_image_get_vectors_iter (image), count = 0;
       list;
       list = g_list_next (list))
    {
      GimpVectors  *vectors = list->data;
      GimpVectors  *new_vectors;

      new_vectors = GIMP_VECTORS (gimp_image_duplicate_item (GIMP_ITEM (vectors),
                                                             new_image));

      if (gimp_image_get_active_vectors (image) == vectors)
        active_vectors = new_vectors;

      gimp_image_add_vectors (new_image, new_vectors,
                              NULL, count++, FALSE);
    }

  return active_vectors;
}
Пример #8
0
static gboolean
gimp_vectors_stroke (GimpItem           *item,
                     GimpDrawable       *drawable,
                     GimpStrokeOptions  *stroke_options,
                     gboolean            push_undo,
                     GimpProgress       *progress,
                     GError            **error)
{
  GimpVectors *vectors = GIMP_VECTORS (item);
  gboolean     retval  = FALSE;

  if (! vectors->strokes)
    {
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                           _("Not enough points to stroke"));
      return FALSE;
    }

  switch (gimp_stroke_options_get_method (stroke_options))
    {
    case GIMP_STROKE_METHOD_LIBART:
      retval = gimp_drawable_stroke_vectors (drawable,
                                             stroke_options,
                                             vectors, push_undo, error);
      break;

    case GIMP_STROKE_METHOD_PAINT_CORE:
      {
        GimpPaintInfo    *paint_info;
        GimpPaintCore    *core;
        GimpPaintOptions *paint_options;
        gboolean          emulate_dynamics;

        paint_info = gimp_context_get_paint_info (GIMP_CONTEXT (stroke_options));

        core = g_object_new (paint_info->paint_type, NULL);

        paint_options = gimp_stroke_options_get_paint_options (stroke_options);
        emulate_dynamics = gimp_stroke_options_get_emulate_dynamics (stroke_options);

        retval = gimp_paint_core_stroke_vectors (core, drawable,
                                                 paint_options,
                                                 emulate_dynamics,
                                                 vectors, push_undo, error);

        g_object_unref (core);
      }
      break;

    default:
      g_return_val_if_reached (FALSE);
    }

  return retval;
}
Пример #9
0
TempBuf *
gimp_vectors_get_new_preview (GimpViewable *viewable,
                              GimpContext  *context,
                              gint          width,
                              gint          height)
{
  GimpVectors *vectors;
  GimpItem    *item;
  GimpStroke  *cur_stroke;
  gdouble      xscale, yscale;
  guchar      *data;
  TempBuf     *temp_buf;
  guchar       white[1] = { 255 };

  vectors = GIMP_VECTORS (viewable);
  item    = GIMP_ITEM (viewable);

  xscale = ((gdouble) width)  / gimp_image_get_width  (item->image);
  yscale = ((gdouble) height) / gimp_image_get_height (item->image);

  temp_buf = temp_buf_new (width, height, 1, 0, 0, white);
  data = temp_buf_data (temp_buf);

  for (cur_stroke = gimp_vectors_stroke_get_next (vectors, NULL);
       cur_stroke;
       cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke))
    {
      GArray   *coords;
      gboolean  closed;
      gint      i;

      coords = gimp_stroke_interpolate (cur_stroke, 0.5, &closed);

      if (coords)
        {
          for (i = 0; i < coords->len; i++)
            {
              GimpCoords point;
              gint       x, y;

              point = g_array_index (coords, GimpCoords, i);

              x = ROUND (point.x * xscale);
              y = ROUND (point.y * yscale);

              if (x >= 0 && y >= 0 && x < width && y < height)
                data[y * width + x] = 0;
            }

          g_array_free (coords, TRUE);
        }
    }

  return temp_buf;
}
Пример #10
0
static GimpItem *
gimp_vectors_duplicate (GimpItem *item,
                        GType     new_type)
{
  GimpItem *new_item;

  g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_VECTORS), NULL);

  new_item = GIMP_ITEM_CLASS (parent_class)->duplicate (item, new_type);

  if (GIMP_IS_VECTORS (new_item))
    {
      GimpVectors *vectors     = GIMP_VECTORS (item);
      GimpVectors *new_vectors = GIMP_VECTORS (new_item);

      gimp_vectors_copy_strokes (vectors, new_vectors);
    }

  return new_item;
}
Пример #11
0
void
vectors_duplicate_cmd_callback (GtkAction *action,
                                gpointer   data)
{
  GimpImage   *image;
  GimpVectors *vectors;
  GimpVectors *new_vectors;
  return_if_no_vectors (image, vectors, data);

  new_vectors = GIMP_VECTORS (gimp_item_duplicate (GIMP_ITEM (vectors),
                                                   G_TYPE_FROM_INSTANCE (vectors)));
  gimp_image_add_vectors (image, new_vectors, -1);
  gimp_image_flush (image);
}
Пример #12
0
static GObject *
gimp_vectors_mod_undo_constructor (GType                  type,
                                   guint                  n_params,
                                   GObjectConstructParam *params)
{
  GObject            *object;
  GimpVectorsModUndo *vectors_mod_undo;
  GimpVectors        *vectors;

  object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);

  vectors_mod_undo = GIMP_VECTORS_MOD_UNDO (object);

  g_assert (GIMP_IS_VECTORS (GIMP_ITEM_UNDO (object)->item));

  vectors = GIMP_VECTORS (GIMP_ITEM_UNDO (object)->item);

  vectors_mod_undo->vectors =
    GIMP_VECTORS (gimp_item_duplicate (GIMP_ITEM (vectors),
                                       G_TYPE_FROM_INSTANCE (vectors),
                                       FALSE));

  return object;
}
Пример #13
0
GimpVectors *
gimp_vectors_new (GimpImage   *image,
                  const gchar *name)
{
  GimpVectors *vectors;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  vectors = GIMP_VECTORS (gimp_item_new (GIMP_TYPE_VECTORS,
                                         image, name,
                                         0, 0,
                                         gimp_image_get_width  (image),
                                         gimp_image_get_height (image)));

  return vectors;
}
Пример #14
0
static gint64
gimp_vectors_get_memsize (GimpObject *object,
                          gint64     *gui_size)
{
  GimpVectors *vectors;
  GList       *list;
  gint64       memsize = 0;

  vectors = GIMP_VECTORS (object);

  for (list = vectors->strokes; list; list = g_list_next (list))
    memsize += (gimp_object_get_memsize (GIMP_OBJECT (list->data), gui_size) +
                sizeof (GList));

  return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
                                                                  gui_size);
}
Пример #15
0
static void
gimp_vectors_to_selection (GimpItem       *item,
                           GimpChannelOps  op,
                           gboolean        antialias,
                           gboolean        feather,
                           gdouble         feather_radius_x,
                           gdouble         feather_radius_y)
{
  GimpVectors *vectors = GIMP_VECTORS (item);
  GimpImage   *image   = gimp_item_get_image (item);

  gimp_channel_select_vectors (gimp_image_get_mask (image),
                               GIMP_ITEM_GET_CLASS (item)->to_selection_desc,
                               vectors,
                               op, antialias,
                               feather, feather_radius_x, feather_radius_x,
                               TRUE);
}
Пример #16
0
static void
gimp_vectors_prop_undo_pop (GimpUndo            *undo,
                            GimpUndoMode         undo_mode,
                            GimpUndoAccumulator *accum)
{
#if 0
  GimpVectorsPropUndo *vectors_prop_undo = GIMP_VECTORS_PROP_UNDO (undo);
  GimpVectors         *vectors           = GIMP_VECTORS (GIMP_ITEM_UNDO (undo)->item);
#endif

  GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);

  switch (undo->undo_type)
    {
    default:
      gimp_assert_not_reached ();
    }
}
Пример #17
0
static void
gimp_vectors_finalize (GObject *object)
{
  GimpVectors *vectors = GIMP_VECTORS (object);

  if (vectors->bezier_desc)
    {
      gimp_bezier_desc_free (vectors->bezier_desc);
      vectors->bezier_desc = NULL;
    }

  if (vectors->strokes)
    {
      g_list_free_full (vectors->strokes, (GDestroyNotify) g_object_unref);
      vectors->strokes = NULL;
    }

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
Пример #18
0
static GString *
gimp_vectors_export (const GimpImage   *image,
                     const GimpVectors *vectors)
{
  GString *str = g_string_new (NULL);

  g_string_append_printf (str,
                          "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
                          "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\"\n"
                          "              \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n"
                          "\n"
                          "<svg xmlns=\"http://www.w3.org/2000/svg\"\n");

  g_string_append (str, "     ");
  gimp_vectors_export_image_size (image, str);
  g_string_append_c (str, '\n');

  g_string_append_printf (str,
                          "     viewBox=\"0 0 %d %d\">\n",
                          gimp_image_get_width  (image),
                          gimp_image_get_height (image));

  if (vectors)
    {
      gimp_vectors_export_path (vectors, str);
    }
  else
    {
      GList *list;

      for (list = gimp_image_get_vectors_iter (image);
           list;
           list = list->next)
        {
          gimp_vectors_export_path (GIMP_VECTORS (list->data), str);
        }
    }

  g_string_append (str, "</svg>\n");

  return str;
}
Пример #19
0
void
vectors_duplicate_cmd_callback (GtkAction *action,
                                gpointer   data)
{
  GimpImage   *image;
  GimpVectors *vectors;
  GimpVectors *new_vectors;
  return_if_no_vectors (image, vectors, data);

  new_vectors = GIMP_VECTORS (gimp_item_duplicate (GIMP_ITEM (vectors),
                                                   G_TYPE_FROM_INSTANCE (vectors)));
  /*  use the actual parent here, not GIMP_IMAGE_ACTIVE_PARENT because
   *  the latter would add a duplicated group inside itself instead of
   *  above it
   */
  gimp_image_add_vectors (image, new_vectors,
                          gimp_vectors_get_parent (vectors), -1,
                          TRUE);
  gimp_image_flush (image);
}
Пример #20
0
static void
gimp_display_shell_drop_vectors (GtkWidget    *widget,
                                 gint          x,
                                 gint          y,
                                 GimpViewable *viewable,
                                 gpointer      data)
{
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image = gimp_display_get_image (shell->display);
  GimpItem         *new_item;

  GIMP_LOG (DND, NULL);

  if (shell->display->gimp->busy)
    return;

  if (! image)
    return;

  new_item = gimp_item_convert (GIMP_ITEM (viewable),
                                image, G_TYPE_FROM_INSTANCE (viewable));

  if (new_item)
    {
      GimpVectors *new_vectors = GIMP_VECTORS (new_item);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Path"));

      gimp_image_add_vectors (image, new_vectors,
                              GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);

      gimp_image_undo_group_end (image);

      gimp_display_shell_dnd_flush (shell, image);
    }
}
Пример #21
0
static guchar *
gimp_vectors_tree_view_drag_svg (GtkWidget *widget,
                                 gsize     *svg_data_len,
                                 gpointer   data)
{
  GimpItemTreeView *view  = GIMP_ITEM_TREE_VIEW (data);
  GimpImage        *image = gimp_item_tree_view_get_image (view);
  GimpItem         *item;
  gchar            *svg_data = NULL;

  item = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->get_active_item (image);

  *svg_data_len = 0;

  if (item)
    {
      svg_data = gimp_vectors_export_string (image, GIMP_VECTORS (item));

      if (svg_data)
        *svg_data_len = strlen (svg_data);
    }

  return (guchar *) svg_data;
}
Пример #22
0
static void
gimp_vectors_tree_view_drop_svg (GimpContainerTreeView   *tree_view,
                                 const gchar             *svg_data,
                                 gsize                    svg_data_len,
                                 GimpViewable            *dest_viewable,
                                 GtkTreeViewDropPosition  drop_pos)
{
  GimpItemTreeView *view  = GIMP_ITEM_TREE_VIEW (tree_view);
  GimpImage        *image = view->image;
  gint              index = -1;
  GError           *error = NULL;

  if (image->gimp->be_verbose)
    g_print ("%s: SVG dropped (len = %d)\n", G_STRFUNC, (gint) svg_data_len);

  if (dest_viewable)
    {
      index = gimp_image_get_vectors_index (image,
                                            GIMP_VECTORS (dest_viewable));

      if (drop_pos == GTK_TREE_VIEW_DROP_AFTER)
        index++;
    }

  if (! gimp_vectors_import_buffer (image, svg_data, svg_data_len,
                                    TRUE, TRUE, index, NULL, &error))
    {
      gimp_message (image->gimp, G_OBJECT (tree_view), GIMP_MESSAGE_ERROR,
                    "%s", error->message);
      g_clear_error (&error);
    }
  else
    {
      gimp_image_flush (image);
    }
}
Пример #23
0
static void
gimp_vectors_scale (GimpItem              *item,
                    gint                   new_width,
                    gint                   new_height,
                    gint                   new_offset_x,
                    gint                   new_offset_y,
                    GimpInterpolationType  interpolation_type,
                    GimpProgress          *progress)
{
  GimpVectors *vectors = GIMP_VECTORS (item);
  GimpImage   *image   = gimp_item_get_image (item);
  GList       *list;

  gimp_vectors_freeze (vectors);

  if (gimp_item_is_attached (item))
    gimp_image_undo_push_vectors_mod (image, NULL, vectors);

  for (list = vectors->strokes; list; list = g_list_next (list))
    {
      GimpStroke *stroke = list->data;

      gimp_stroke_scale (stroke,
                         (gdouble) new_width  / (gdouble) gimp_item_get_width  (item),
                         (gdouble) new_height / (gdouble) gimp_item_get_height (item));
      gimp_stroke_translate (stroke, new_offset_x, new_offset_y);
    }

  GIMP_ITEM_CLASS (parent_class)->scale (item,
                                         gimp_image_get_width  (image),
                                         gimp_image_get_height (image),
                                         0, 0,
                                         interpolation_type, progress);

  gimp_vectors_thaw (vectors);
}
Пример #24
0
GimpImage *
gimp_image_duplicate (GimpImage *image)
{
  GimpImage    *new_image;
  GimpLayer    *floating_layer;
  GList        *list;
  GimpLayer    *active_layer              = NULL;
  GimpChannel  *active_channel            = NULL;
  GimpVectors  *active_vectors            = NULL;
  GimpDrawable *new_floating_sel_drawable = NULL;
  GimpDrawable *floating_sel_drawable     = NULL;
  gchar        *filename;
  gint          count;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  gimp_set_busy_until_idle (image->gimp);

  /*  Create a new image  */
  new_image = gimp_create_image (image->gimp,
                                 image->width, image->height,
                                 image->base_type,
                                 FALSE);
  gimp_image_undo_disable (new_image);

  /*  Store the folder to be used by the save dialog  */
  filename = gimp_image_get_filename (image);
  if (filename)
    {
      g_object_set_data_full (G_OBJECT (new_image), "gimp-image-dirname",
                              g_path_get_dirname (filename),
                              (GDestroyNotify) g_free);
      g_free (filename);
    }

  /*  Copy the colormap if necessary  */
  if (new_image->base_type == GIMP_INDEXED)
    gimp_image_set_colormap (new_image,
                             gimp_image_get_colormap (image),
                             gimp_image_get_colormap_size (image),
                             FALSE);

  /*  Copy resolution information  */
  new_image->xresolution     = image->xresolution;
  new_image->yresolution     = image->yresolution;
  new_image->resolution_unit = image->resolution_unit;

  /*  Copy floating layer  */
  floating_layer = gimp_image_floating_sel (image);
  if (floating_layer)
    {
      floating_sel_relax (floating_layer, FALSE);

      floating_sel_drawable = floating_layer->fs.drawable;
      floating_layer = NULL;
    }

  /*  Copy the layers  */
  for (list = GIMP_LIST (image->layers)->list, count = 0;
       list;
       list = g_list_next (list))
    {
      GimpLayer *layer = list->data;
      GimpLayer *new_layer;

      new_layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (layer),
                                                 new_image,
                                                 G_TYPE_FROM_INSTANCE (layer),
                                                 FALSE));

      /*  Make sure the copied layer doesn't say: "<old layer> copy"  */
      gimp_object_set_name (GIMP_OBJECT (new_layer),
                            gimp_object_get_name (GIMP_OBJECT (layer)));

      /*  Make sure that if the layer has a layer mask,
       *  its name isn't screwed up
       */
      if (new_layer->mask)
        gimp_object_set_name (GIMP_OBJECT (new_layer->mask),
                              gimp_object_get_name (GIMP_OBJECT (layer->mask)));

      if (gimp_image_get_active_layer (image) == layer)
        active_layer = new_layer;

      if (image->floating_sel == layer)
        floating_layer = new_layer;

      if (floating_sel_drawable == GIMP_DRAWABLE (layer))
        new_floating_sel_drawable = GIMP_DRAWABLE (new_layer);

      if (floating_layer != new_layer)
        gimp_image_add_layer (new_image, new_layer, count++);
    }

  /*  Copy the channels  */
  for (list = GIMP_LIST (image->channels)->list, count = 0;
       list;
       list = g_list_next (list))
    {
      GimpChannel *channel = list->data;
      GimpChannel *new_channel;

      new_channel =
        GIMP_CHANNEL (gimp_item_convert (GIMP_ITEM (channel),
                                         new_image,
                                         G_TYPE_FROM_INSTANCE (channel),
                                         FALSE));

      /*  Make sure the copied channel doesn't say: "<old channel> copy"  */
      gimp_object_set_name (GIMP_OBJECT (new_channel),
                            gimp_object_get_name (GIMP_OBJECT (channel)));

      if (gimp_image_get_active_channel (image) == channel)
        active_channel = (new_channel);

      if (floating_sel_drawable == GIMP_DRAWABLE (channel))
        new_floating_sel_drawable = GIMP_DRAWABLE (new_channel);

      gimp_image_add_channel (new_image, new_channel, count++);
    }

  /*  Copy any vectors  */
  for (list = GIMP_LIST (image->vectors)->list, count = 0;
       list;
       list = g_list_next (list))
    {
      GimpVectors *vectors = list->data;
      GimpVectors *new_vectors;

      new_vectors =
        GIMP_VECTORS (gimp_item_convert (GIMP_ITEM (vectors),
                                         new_image,
                                         G_TYPE_FROM_INSTANCE (vectors),
                                         FALSE));

      /*  Make sure the copied vectors doesn't say: "<old vectors> copy"  */
      gimp_object_set_name (GIMP_OBJECT (new_vectors),
                            gimp_object_get_name (GIMP_OBJECT (vectors)));

      if (gimp_image_get_active_vectors (image) == vectors)
        active_vectors = new_vectors;

      gimp_image_add_vectors (new_image, new_vectors, count++);
    }

  /*  Copy the selection mask  */
  {
    TileManager *src_tiles;
    TileManager *dest_tiles;
    PixelRegion  srcPR, destPR;

    src_tiles  =
      gimp_drawable_get_tiles (GIMP_DRAWABLE (image->selection_mask));
    dest_tiles =
      gimp_drawable_get_tiles (GIMP_DRAWABLE (new_image->selection_mask));

    pixel_region_init (&srcPR, src_tiles,
                       0, 0, image->width, image->height, FALSE);
    pixel_region_init (&destPR, dest_tiles,
                       0, 0, image->width, image->height, TRUE);

    copy_region (&srcPR, &destPR);

    new_image->selection_mask->bounds_known   = FALSE;
    new_image->selection_mask->boundary_known = FALSE;
  }

  if (floating_layer)
    floating_sel_attach (floating_layer, new_floating_sel_drawable);

  /*  Set active layer, active channel, active vectors  */
  if (active_layer)
    gimp_image_set_active_layer (new_image, active_layer);

  if (active_channel)
    gimp_image_set_active_channel (new_image, active_channel);

  if (active_vectors)
    gimp_image_set_active_vectors (new_image, active_vectors);

  /*  Copy state of all color channels  */
  for (count = 0; count < MAX_CHANNELS; count++)
    {
      new_image->visible[count] = image->visible[count];
      new_image->active[count]  = image->active[count];
    }

  /*  Copy any guides  */
  for (list = image->guides; 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:
          gimp_image_add_hguide (new_image, position, FALSE);
          break;

        case GIMP_ORIENTATION_VERTICAL:
          gimp_image_add_vguide (new_image, position, FALSE);
          break;

        default:
          g_error ("Unknown guide orientation.\n");
        }
    }

  /*  Copy any sample points  */
  for (list = image->sample_points; list; list = g_list_next (list))
    {
      GimpSamplePoint *sample_point = list->data;

      gimp_image_add_sample_point_at_pos (new_image,
                                          sample_point->x,
                                          sample_point->y,
                                          FALSE);
    }

  /*  Copy the grid  */
  if (image->grid)
    gimp_image_set_grid (new_image, image->grid, FALSE);

  /*  Copy the quick mask info  */
  new_image->quick_mask_state    = image->quick_mask_state;
  new_image->quick_mask_inverted = image->quick_mask_inverted;
  new_image->quick_mask_color    = image->quick_mask_color;

  /*  Copy parasites  */
  if (image->parasites)
    {
      g_object_unref (new_image->parasites);
      new_image->parasites = gimp_parasite_list_copy (image->parasites);
    }

  gimp_image_undo_enable (new_image);

  return new_image;
}
Пример #25
0
static void
gimp_align_tool_draw (GimpDrawTool *draw_tool)
{
    GimpAlignTool *align_tool = GIMP_ALIGN_TOOL (draw_tool);
    GList         *list;
    gint           x, y, w, h;

    /* draw rubber-band rectangle */
    x = MIN (align_tool->x2, align_tool->x1);
    y = MIN (align_tool->y2, align_tool->y1);
    w = MAX (align_tool->x2, align_tool->x1) - x;
    h = MAX (align_tool->y2, align_tool->y1) - y;

    gimp_draw_tool_add_rectangle (draw_tool, FALSE, x, y, w, h);

    for (list = align_tool->selected_objects;
            list;
            list = g_list_next (list))
    {
        if (GIMP_IS_ITEM (list->data))
        {
            GimpItem *item = list->data;

            if (GIMP_IS_VECTORS (item))
            {
                gdouble x1_f, y1_f, x2_f, y2_f;

                gimp_vectors_bounds (GIMP_VECTORS (item),
                                     &x1_f, &y1_f,
                                     &x2_f, &y2_f);
                x = ROUND (x1_f);
                y = ROUND (y1_f);
                w = ROUND (x2_f - x1_f);
                h = ROUND (y2_f - y1_f);
            }
            else
            {
                gimp_item_get_offset (item, &x, &y);

                w = gimp_item_get_width  (item);
                h = gimp_item_get_height (item);
            }

            gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
                                       x, y,
                                       GIMP_TOOL_HANDLE_SIZE_SMALL,
                                       GIMP_TOOL_HANDLE_SIZE_SMALL,
                                       GIMP_HANDLE_ANCHOR_NORTH_WEST);
            gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
                                       x + w, y,
                                       GIMP_TOOL_HANDLE_SIZE_SMALL,
                                       GIMP_TOOL_HANDLE_SIZE_SMALL,
                                       GIMP_HANDLE_ANCHOR_NORTH_EAST);
            gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
                                       x, y + h,
                                       GIMP_TOOL_HANDLE_SIZE_SMALL,
                                       GIMP_TOOL_HANDLE_SIZE_SMALL,
                                       GIMP_HANDLE_ANCHOR_SOUTH_WEST);
            gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
                                       x + w, y + h,
                                       GIMP_TOOL_HANDLE_SIZE_SMALL,
                                       GIMP_TOOL_HANDLE_SIZE_SMALL,
                                       GIMP_HANDLE_ANCHOR_SOUTH_EAST);
        }
        else if (GIMP_IS_GUIDE (list->data))
        {
            GimpGuide *guide = list->data;
            GimpImage *image = gimp_display_get_image (GIMP_TOOL (draw_tool)->display);
            gint       x, y;
            gint       w, h;

            switch (gimp_guide_get_orientation (guide))
            {
            case GIMP_ORIENTATION_VERTICAL:
                x = gimp_guide_get_position (guide);
                h = gimp_image_get_height (image);
                gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
                                           x, h,
                                           GIMP_TOOL_HANDLE_SIZE_SMALL,
                                           GIMP_TOOL_HANDLE_SIZE_SMALL,
                                           GIMP_HANDLE_ANCHOR_SOUTH);
                gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
                                           x, 0,
                                           GIMP_TOOL_HANDLE_SIZE_SMALL,
                                           GIMP_TOOL_HANDLE_SIZE_SMALL,
                                           GIMP_HANDLE_ANCHOR_NORTH);
                break;

            case GIMP_ORIENTATION_HORIZONTAL:
                y = gimp_guide_get_position (guide);
                w = gimp_image_get_width (image);
                gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
                                           w, y,
                                           GIMP_TOOL_HANDLE_SIZE_SMALL,
                                           GIMP_TOOL_HANDLE_SIZE_SMALL,
                                           GIMP_HANDLE_ANCHOR_EAST);
                gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
                                           0, y,
                                           GIMP_TOOL_HANDLE_SIZE_SMALL,
                                           GIMP_TOOL_HANDLE_SIZE_SMALL,
                                           GIMP_HANDLE_ANCHOR_WEST);
                break;

            default:
                break;
            }
        }
    }
}
Пример #26
0
GimpVectors *
gimp_image_merge_visible_vectors (GimpImage  *image,
                                  GError    **error)
{
  GList       *list           = NULL;
  GSList      *merge_list     = NULL;
  GSList      *cur_item       = NULL;
  GimpVectors *vectors        = NULL;
  GimpVectors *target_vectors = NULL;
  gchar       *name           = NULL;
  gint         pos            = 0;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  for (list = GIMP_LIST (image->vectors)->list;
       list;
       list = g_list_next (list))
    {
      vectors = list->data;

      if (gimp_item_get_visible (GIMP_ITEM (vectors)))
        merge_list = g_slist_append (merge_list, vectors);
    }

  if (merge_list && merge_list->next)
    {
      gimp_set_busy (image->gimp);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE,
                                   _("Merge Visible Paths"));

      cur_item = merge_list;
      vectors = GIMP_VECTORS (cur_item->data);

      name = g_strdup (gimp_object_get_name (GIMP_OBJECT (vectors)));
      target_vectors = GIMP_VECTORS (gimp_item_duplicate (GIMP_ITEM (vectors),
                                                          GIMP_TYPE_VECTORS));
      pos = gimp_image_get_vectors_index (image, vectors);
      gimp_image_remove_vectors (image, vectors);
      cur_item = cur_item->next;

      while (cur_item)
        {
          vectors = GIMP_VECTORS (cur_item->data);
          gimp_vectors_add_strokes (vectors, target_vectors);
          gimp_image_remove_vectors (image, vectors);

          cur_item = g_slist_next (cur_item);
        }

      gimp_object_take_name (GIMP_OBJECT (target_vectors), name);

      g_slist_free (merge_list);

      gimp_image_add_vectors (image, target_vectors, pos);
      gimp_unset_busy (image->gimp);

      gimp_image_undo_group_end (image);

      return target_vectors;
    }
  else
    {
      g_set_error (error, 0, 0,
                   _("Not enough visible paths for a merge. "
                     "There must be at least two."));
      return NULL;
    }
}
Пример #27
0
GimpVectors *
gimp_image_merge_visible_vectors (GimpImage  *image,
                                  GError    **error)
{
  GList       *list;
  GList       *merge_list = NULL;
  GimpVectors *vectors;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  for (list = gimp_image_get_vectors_iter (image);
       list;
       list = g_list_next (list))
    {
      vectors = list->data;

      if (gimp_item_get_visible (GIMP_ITEM (vectors)))
        merge_list = g_list_prepend (merge_list, vectors);
    }

  merge_list = g_list_reverse (merge_list);

  if (merge_list && merge_list->next)
    {
      GimpVectors *target_vectors;
      gchar       *name;
      gint         pos;

      gimp_set_busy (image->gimp);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE,
                                   C_("undo-type", "Merge Visible Paths"));

      vectors = GIMP_VECTORS (merge_list->data);

      name = g_strdup (gimp_object_get_name (vectors));
      pos = gimp_item_get_index (GIMP_ITEM (vectors));

      target_vectors = GIMP_VECTORS (gimp_item_duplicate (GIMP_ITEM (vectors),
                                                          GIMP_TYPE_VECTORS));
      gimp_image_remove_vectors (image, vectors, TRUE, NULL);

      for (list = g_list_next (merge_list);
           list;
           list = g_list_next (list))
        {
          vectors = list->data;

          gimp_vectors_add_strokes (vectors, target_vectors);
          gimp_image_remove_vectors (image, vectors, TRUE, NULL);
        }

      gimp_object_take_name (GIMP_OBJECT (target_vectors), name);

      g_list_free (merge_list);

      /* FIXME tree */
      gimp_image_add_vectors (image, target_vectors, NULL, pos, TRUE);
      gimp_unset_busy (image->gimp);

      gimp_image_undo_group_end (image);

      return target_vectors;
    }
  else
    {
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
			   _("Not enough visible paths for a merge. "
			     "There must be at least two."));
      return NULL;
    }
}
Пример #28
0
static void
compute_offset (GObject *object,
                GimpAlignmentType  alignment)
{
  gint object_offset_x = 0;
  gint object_offset_y = 0;
  gint object_height   = 0;
  gint object_width    = 0;
  gint offset          = 0;

  if (GIMP_IS_IMAGE (object))
    {
      GimpImage *image = GIMP_IMAGE (object);

      object_offset_x = 0;
      object_offset_y = 0;
      object_height   = gimp_image_get_height (image);
      object_width    = gimp_image_get_width (image);
    }
  else if (GIMP_IS_CHANNEL (object))
    {
      /* for channels, we use the bounds of the visible area, not
         the layer bounds.  This includes the selection channel */

      GimpChannel *channel = GIMP_CHANNEL (object);

      if (gimp_channel_is_empty (channel))
        {
          /* fall back on using the offsets instead */
          GimpItem *item = GIMP_ITEM (object);

          gimp_item_get_offset (item, &object_offset_x, &object_offset_y);
          object_width  = gimp_item_get_width  (item);
          object_height = gimp_item_get_height (item);
        }
      else
        {
          gint x1, x2, y1, y2;

          gimp_channel_bounds (channel, &x1, &y1, &x2, &y2);
          object_offset_x = x1;
          object_offset_y = y1;
          object_width    = x2 - x1;
          object_height   = y2 - y1;
        }
    }
  else if (GIMP_IS_ITEM (object))
    {
      GimpItem *item = GIMP_ITEM (object);

      if (GIMP_IS_VECTORS (object))
        {
          gdouble x1_f, y1_f, x2_f, y2_f;

          gimp_vectors_bounds (GIMP_VECTORS (item),
                               &x1_f, &y1_f,
                               &x2_f, &y2_f);

          object_offset_x = ROUND (x1_f);
          object_offset_y = ROUND (y1_f);
          object_height   = ROUND (y2_f - y1_f);
          object_width    = ROUND (x2_f - x1_f);
        }
      else
        {
          gimp_item_get_offset (item, &object_offset_x, &object_offset_y);
          object_width  = gimp_item_get_width  (item);
          object_height = gimp_item_get_height (item);
        }
    }
  else if (GIMP_IS_GUIDE (object))
    {
      GimpGuide *guide = GIMP_GUIDE (object);

      switch (gimp_guide_get_orientation (guide))
        {
        case GIMP_ORIENTATION_VERTICAL:
          object_offset_x = gimp_guide_get_position (guide);
          object_width = 0;
          break;

        case GIMP_ORIENTATION_HORIZONTAL:
          object_offset_y = gimp_guide_get_position (guide);
          object_height = 0;
          break;

        default:
          break;
        }
    }
  else
    {
      g_printerr ("Alignment object is not an image, item or guide.\n");
    }

  switch (alignment)
    {
    case GIMP_ALIGN_LEFT:
    case GIMP_ARRANGE_LEFT:
      offset = object_offset_x;
      break;
    case GIMP_ALIGN_HCENTER:
    case GIMP_ARRANGE_HCENTER:
      offset = object_offset_x + object_width/2;
      break;
    case GIMP_ALIGN_RIGHT:
    case GIMP_ARRANGE_RIGHT:
      offset = object_offset_x + object_width;
      break;
    case GIMP_ALIGN_TOP:
    case GIMP_ARRANGE_TOP:
      offset = object_offset_y;
      break;
    case GIMP_ALIGN_VCENTER:
    case GIMP_ARRANGE_VCENTER:
      offset = object_offset_y + object_height/2;
      break;
    case GIMP_ALIGN_BOTTOM:
    case GIMP_ARRANGE_BOTTOM:
      offset = object_offset_y + object_height;
      break;
    default:
      g_assert_not_reached ();
    }

  g_object_set_data (object, "align-offset",
                     GINT_TO_POINTER (offset));
}
Пример #29
0
static gboolean
gimp_vectors_bounds (GimpItem *item,
                     gdouble  *x,
                     gdouble  *y,
                     gdouble  *width,
                     gdouble  *height)
{
  GimpVectors *vectors = GIMP_VECTORS (item);

  if (! vectors->bounds_valid)
    {
      GimpStroke *stroke;

      vectors->bounds_empty = TRUE;
      vectors->bounds_x1 = vectors->bounds_x2 = 0.0;
      vectors->bounds_y1 = vectors->bounds_y2 = 0.0;

      for (stroke = gimp_vectors_stroke_get_next (vectors, NULL);
           stroke;
           stroke = gimp_vectors_stroke_get_next (vectors, stroke))
        {
          GArray   *stroke_coords;
          gboolean  closed;

          stroke_coords = gimp_stroke_interpolate (stroke, 1.0, &closed);

          if (stroke_coords)
            {
              GimpCoords point;
              gint       i;

              if (vectors->bounds_empty && stroke_coords->len > 0)
                {
                  point = g_array_index (stroke_coords, GimpCoords, 0);

                  vectors->bounds_x1 = vectors->bounds_x2 = point.x;
                  vectors->bounds_y1 = vectors->bounds_y2 = point.y;

                  vectors->bounds_empty = FALSE;
                }

              for (i = 0; i < stroke_coords->len; i++)
                {
                  point = g_array_index (stroke_coords, GimpCoords, i);

                  vectors->bounds_x1 = MIN (vectors->bounds_x1, point.x);
                  vectors->bounds_y1 = MIN (vectors->bounds_y1, point.y);
                  vectors->bounds_x2 = MAX (vectors->bounds_x2, point.x);
                  vectors->bounds_y2 = MAX (vectors->bounds_y2, point.y);
                }

              g_array_free (stroke_coords, TRUE);
            }
        }

      vectors->bounds_valid = TRUE;
    }

  *x      = vectors->bounds_x1;
  *y      = vectors->bounds_y1;
  *width  = vectors->bounds_x2 - vectors->bounds_x1;
  *height = vectors->bounds_y2 - vectors->bounds_y1;

  return ! vectors->bounds_empty;
}