Exemple #1
0
/**
 * gimp_image_item_list_get_list:
 * @image:   An @image.
 * @type:    Which type of items to return.
 * @set:     Set the returned items are part of.
 *
 * This function returns a #GList of #GimpItem<!-- -->s for which the
 * @type and @set criterions match.
 *
 * Return value: The list of items.
 **/
GList *
gimp_image_item_list_get_list (GimpImage        *image,
                               GimpItemTypeMask  type,
                               GimpItemSet       set)
{
  GList *all_items;
  GList *list;
  GList *return_list = NULL;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  if (type & GIMP_ITEM_TYPE_LAYERS)
    {
      all_items = gimp_image_get_layer_list (image);

      for (list = all_items; list; list = g_list_next (list))
        {
          GimpItem *item = list->data;

          if (gimp_item_is_in_set (item, set))
            return_list = g_list_prepend (return_list, item);
        }

      g_list_free (all_items);
    }

  if (type & GIMP_ITEM_TYPE_CHANNELS)
    {
      all_items = gimp_image_get_channel_list (image);

      for (list = all_items; list; list = g_list_next (list))
        {
          GimpItem *item = list->data;

          if (gimp_item_is_in_set (item, set))
            return_list = g_list_prepend (return_list, item);
        }

      g_list_free (all_items);
    }

  if (type & GIMP_ITEM_TYPE_VECTORS)
    {
      all_items = gimp_image_get_vectors_list (image);

      for (list = all_items; list; list = g_list_next (list))
        {
          GimpItem *item = list->data;

          if (gimp_item_is_in_set (item, set))
            return_list = g_list_prepend (return_list, item);
        }

      g_list_free (all_items);
    }

  return g_list_reverse (return_list);
}
Exemple #2
0
gboolean
gimp_draw_tool_on_vectors (GimpDrawTool      *draw_tool,
                           GimpDisplay       *display,
                           const GimpCoords  *coords,
                           gint               width,
                           gint               height,
                           GimpCoords        *ret_coords,
                           gdouble           *ret_pos,
                           GimpAnchor       **ret_segment_start,
                           GimpAnchor       **ret_segment_end,
                           GimpStroke       **ret_stroke,
                           GimpVectors      **ret_vectors)
{
  GList *all_vectors;
  GList *list;

  if (ret_coords)        *ret_coords         = *coords;
  if (ret_pos)           *ret_pos            = -1.0;
  if (ret_segment_start) *ret_segment_start  = NULL;
  if (ret_segment_end)   *ret_segment_end    = NULL;
  if (ret_stroke)        *ret_stroke         = NULL;
  if (ret_vectors)       *ret_vectors        = NULL;

  all_vectors = gimp_image_get_vectors_list (gimp_display_get_image (display));

  for (list = all_vectors; list; list = g_list_next (list))
    {
      GimpVectors *vectors = list->data;

      if (! gimp_item_get_visible (GIMP_ITEM (vectors)))
        continue;

      if (gimp_draw_tool_on_vectors_curve (draw_tool,
                                           display,
                                           vectors, coords,
                                           width, height,
                                           ret_coords,
                                           ret_pos,
                                           ret_segment_start,
                                           ret_segment_end,
                                           ret_stroke))
        {
          if (ret_vectors)
            *ret_vectors = vectors;

          g_list_free (all_vectors);

          return TRUE;
        }
    }

  g_list_free (all_vectors);

  return FALSE;
}
void
gimp_image_scale (GimpImage             *image,
                  gint                   new_width,
                  gint                   new_height,
                  GimpInterpolationType  interpolation_type,
                  GimpProgress          *progress)
{
    GimpProgress *sub_progress;
    GList        *all_layers;
    GList        *all_channels;
    GList        *all_vectors;
    GList        *list;
    gint          old_width;
    gint          old_height;
    gint          offset_x;
    gint          offset_y;
    gdouble       img_scale_w      = 1.0;
    gdouble       img_scale_h      = 1.0;
    gint          progress_steps;
    gint          progress_current = 0;

    g_return_if_fail (GIMP_IS_IMAGE (image));
    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);

    sub_progress = gimp_sub_progress_new (progress);

    all_layers   = gimp_image_get_layer_list (image);
    all_channels = gimp_image_get_channel_list (image);
    all_vectors  = gimp_image_get_vectors_list (image);

    progress_steps = (g_list_length (all_layers)   +
                      g_list_length (all_channels) +
                      g_list_length (all_vectors)  +
                      1 /* selection */);

    g_object_freeze_notify (G_OBJECT (image));

    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_SCALE,
                                 C_("undo-type", "Scale Image"));

    old_width   = gimp_image_get_width  (image);
    old_height  = gimp_image_get_height (image);
    img_scale_w = (gdouble) new_width  / (gdouble) old_width;
    img_scale_h = (gdouble) new_height / (gdouble) old_height;

    offset_x = (old_width  - new_width)  / 2;
    offset_y = (old_height - new_height) / 2;

    /*  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 early, so below image item setters
     *  (esp. guides and sample points) don't choke about moving stuff
     *  out of the image
     */
    g_object_set (image,
                  "width",  new_width,
                  "height", new_height,
                  NULL);

    /*  Scale all channels  */
    for (list = all_channels; list; list = g_list_next (list))
    {
        GimpItem *item = list->data;

        gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (sub_progress),
                                    progress_current++, progress_steps);

        gimp_item_scale (item,
                         new_width, new_height, 0, 0,
                         interpolation_type, sub_progress);
    }

    /*  Scale all vectors  */
    for (list = all_vectors; list; list = g_list_next (list))
    {
        GimpItem *item = list->data;

        gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (sub_progress),
                                    progress_current++, progress_steps);

        gimp_item_scale (item,
                         new_width, new_height, 0, 0,
                         interpolation_type, sub_progress);
    }

    /*  Don't forget the selection mask!  */
    gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (sub_progress),
                                progress_current++, progress_steps);

    gimp_item_scale (GIMP_ITEM (gimp_image_get_mask (image)),
                     new_width, new_height, 0, 0,
                     interpolation_type, sub_progress);

    /*  Scale all layers  */
    for (list = all_layers; list; list = g_list_next (list))
    {
        GimpItem *item = list->data;

        gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (sub_progress),
                                    progress_current++, progress_steps);

        /*  group layers are updated automatically  */
        if (gimp_viewable_get_children (GIMP_VIEWABLE (item)))
        {
            gimp_group_layer_suspend_resize (GIMP_GROUP_LAYER (item), FALSE);
            continue;
        }

        if (! gimp_item_scale_by_factors (item,
                                          img_scale_w, img_scale_h,
                                          interpolation_type, sub_progress))
        {
            /* Since 0 < img_scale_w, img_scale_h, failure due to one or more
             * vanishing scaled layer dimensions. Implicit delete implemented
             * here. Upstream warning implemented in resize_check_layer_scaling(),
             * which offers the user the chance to bail out.
             */
            gimp_image_remove_layer (image, GIMP_LAYER (item), TRUE, NULL);
        }
    }

    for (list = all_layers; list; list = g_list_next (list))
        if (gimp_viewable_get_children (list->data))
            gimp_group_layer_resume_resize (list->data, FALSE);


    /*  Scale 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:
            gimp_image_move_guide (image, guide,
                                   (position * new_height) / old_height,
                                   TRUE);
            break;

        case GIMP_ORIENTATION_VERTICAL:
            gimp_image_move_guide (image, guide,
                                   (position * new_width) / old_width,
                                   TRUE);
            break;

        default:
            break;
        }
    }

    /*  Scale all sample points  */
    for (list = gimp_image_get_sample_points (image);
            list;
            list = g_list_next (list))
    {
        GimpSamplePoint *sample_point = list->data;

        gimp_image_move_sample_point (image, sample_point,
                                      sample_point->x * new_width  / old_width,
                                      sample_point->y * new_height / old_height,
                                      TRUE);
    }

    gimp_image_undo_group_end (image);

    g_list_free (all_layers);
    g_list_free (all_channels);
    g_list_free (all_vectors);

    g_object_unref (sub_progress);

    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);
}