static void
gimp_display_shell_sample_point_add_handler (GimpImage        *image,
                                             GimpSamplePoint  *sample_point,
                                             GimpDisplayShell *shell)
{
  GimpCanvasProxyGroup *group = GIMP_CANVAS_PROXY_GROUP (shell->sample_points);
  GimpCanvasItem       *item;
  GList                *list;
  gint                  x;
  gint                  y;
  gint                  i;

  gimp_sample_point_get_position (sample_point, &x, &y);

  item = gimp_canvas_sample_point_new (shell, x, y, 0, TRUE);

  gimp_canvas_proxy_group_add_item (group, sample_point, item);
  g_object_unref (item);

  for (list = gimp_image_get_sample_points (image), i = 1;
       list;
       list = g_list_next (list), i++)
    {
      GimpSamplePoint *sample_point = list->data;

      item = gimp_canvas_proxy_group_get_item (group, sample_point);

      if (item)
        g_object_set (item,
                      "index", i,
                      NULL);
    }
}
Ejemplo n.º 2
0
static gboolean
gimp_sample_point_editor_update (GimpSamplePointEditor *editor)
{
  GimpImageEditor *image_editor = GIMP_IMAGE_EDITOR (editor);
  GList           *sample_points;
  gint             n_points     = 0;
  GList           *list;
  gint             i;

  editor->dirty_idle_id = 0;

  if (! image_editor->image)
    return FALSE;

  sample_points = gimp_image_get_sample_points (image_editor->image);

  n_points = MIN (4, g_list_length (sample_points));

  for (i = 0, list = sample_points;
       i < n_points;
       i++, list = g_list_next (list))
    {
      if (editor->dirty[i])
        {
          GimpSamplePoint *sample_point = list->data;
          GimpColorFrame  *color_frame;
          const Babl      *format;
          guchar           pixel[32];
          GimpRGB          color;
          gint             x;
          gint             y;

          editor->dirty[i] = FALSE;

          color_frame = GIMP_COLOR_FRAME (editor->color_frames[i]);

          gimp_sample_point_get_position (sample_point, &x, &y);

          if (gimp_image_pick_color (image_editor->image, NULL,
                                     x, y,
                                     editor->sample_merged,
                                     FALSE, 0.0,
                                     &format,
                                     pixel,
                                     &color))
            {
              gimp_color_frame_set_color (color_frame, FALSE,
                                          format, pixel, &color);
            }
          else
            {
              gimp_color_frame_set_invalid (color_frame);
            }
        }
    }

  return FALSE;
}
Ejemplo n.º 3
0
static void
gimp_color_tool_button_press (GimpTool            *tool,
                              const GimpCoords    *coords,
                              guint32              time,
                              GdkModifierType      state,
                              GimpButtonPressType  press_type,
                              GimpDisplay         *display)
{
  GimpColorTool    *color_tool = GIMP_COLOR_TOOL (tool);
  GimpDisplayShell *shell      = gimp_display_get_shell (display);

  /*  Chain up to activate the tool  */
  GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time, state,
                                                press_type, display);

  if (! color_tool->enabled)
    return;

  if (color_tool->sample_point)
    {
      color_tool->moving_sample_point = TRUE;
      gimp_sample_point_get_position (color_tool->sample_point,
                                      &color_tool->sample_point_x,
                                      &color_tool->sample_point_y);

      gimp_tool_control_set_scroll_lock (tool->control, TRUE);

      gimp_display_shell_selection_pause (shell);

      if (! gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tool)))
        gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);

      gimp_tool_push_status_coords (tool, display,
                                    gimp_tool_control_get_precision (tool->control),
                                    _("Move Sample Point: "),
                                    color_tool->sample_point_x,
                                    ", ",
                                    color_tool->sample_point_y,
                                    NULL);
    }
  else
    {
      color_tool->center_x = coords->x;
      color_tool->center_y = coords->y;

      gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);

      gimp_color_tool_pick (color_tool, GIMP_COLOR_PICK_STATE_START,
                            coords->x, coords->y);
    }
}
Ejemplo n.º 4
0
static void
gimp_color_tool_draw (GimpDrawTool *draw_tool)
{
  GimpColorTool *color_tool = GIMP_COLOR_TOOL (draw_tool);

  if (color_tool->enabled)
    {
      if (color_tool->sample_point)
        {
          GimpImage      *image = gimp_display_get_image (draw_tool->display);
          GimpCanvasItem *item;
          gint            index;
          gint            x;
          gint            y;

          gimp_sample_point_get_position (color_tool->sample_point, &x, &y);

          index = g_list_index (gimp_image_get_sample_points (image),
                                color_tool->sample_point) + 1;

          item = gimp_draw_tool_add_sample_point (draw_tool, x, y, index);
          gimp_canvas_item_set_highlight (item, TRUE);
        }

      if (color_tool->moving_sample_point)
        {
          if (color_tool->sample_point_x != SAMPLE_POINT_POSITION_INVALID &&
              color_tool->sample_point_y != SAMPLE_POINT_POSITION_INVALID)
            {
              gimp_draw_tool_add_crosshair (draw_tool,
                                            color_tool->sample_point_x,
                                            color_tool->sample_point_y);
            }
        }
      else if (color_tool->options->sample_average &&
               gimp_tool_control_is_active (GIMP_TOOL (draw_tool)->control))
        {
          gdouble radius = color_tool->options->average_radius;

          gimp_draw_tool_add_rectangle (draw_tool,
                                        FALSE,
                                        color_tool->center_x - radius,
                                        color_tool->center_y - radius,
                                        2 * radius + 1,
                                        2 * radius + 1);
        }
    }
}
static void
gimp_display_shell_sample_point_move_handler (GimpImage        *image,
                                              GimpSamplePoint  *sample_point,
                                              GimpDisplayShell *shell)
{
  GimpCanvasProxyGroup *group = GIMP_CANVAS_PROXY_GROUP (shell->sample_points);
  GimpCanvasItem       *item;
  gint                  x;
  gint                  y;

  item = gimp_canvas_proxy_group_get_item (group, sample_point);

  gimp_sample_point_get_position (sample_point, &x, &y);

  gimp_canvas_sample_point_set (item, x, y);
}
Ejemplo n.º 6
0
static void
gimp_sample_point_undo_constructed (GObject *object)
{
  GimpSamplePointUndo *sample_point_undo = GIMP_SAMPLE_POINT_UNDO (object);
  GimpSamplePoint     *sample_point;

  G_OBJECT_CLASS (parent_class)->constructed (object);

  sample_point = GIMP_SAMPLE_POINT (GIMP_AUX_ITEM_UNDO (object)->aux_item);

  gimp_assert (GIMP_IS_SAMPLE_POINT (sample_point));

  gimp_sample_point_get_position (sample_point,
                                  &sample_point_undo->x,
                                  &sample_point_undo->y);
  sample_point_undo->pick_mode = gimp_sample_point_get_pick_mode (sample_point);
}
Ejemplo n.º 7
0
static void
gimp_sample_point_undo_pop (GimpUndo              *undo,
                            GimpUndoMode           undo_mode,
                            GimpUndoAccumulator   *accum)
{
  GimpSamplePointUndo *sample_point_undo = GIMP_SAMPLE_POINT_UNDO (undo);
  GimpSamplePoint     *sample_point;
  gint                 x;
  gint                 y;
  GimpColorPickMode    pick_mode;

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

  sample_point = GIMP_SAMPLE_POINT (GIMP_AUX_ITEM_UNDO (undo)->aux_item);

  gimp_sample_point_get_position (sample_point, &x, &y);
  pick_mode = gimp_sample_point_get_pick_mode (sample_point);

  if (x == GIMP_SAMPLE_POINT_POSITION_UNDEFINED)
    {
      gimp_image_add_sample_point (undo->image,
                                   sample_point,
                                   sample_point_undo->x,
                                   sample_point_undo->y);
    }
  else if (sample_point_undo->x == GIMP_SAMPLE_POINT_POSITION_UNDEFINED)
    {
      gimp_image_remove_sample_point (undo->image, sample_point, FALSE);
    }
  else
    {
      gimp_sample_point_set_position (sample_point,
                                      sample_point_undo->x,
                                      sample_point_undo->y);
      gimp_sample_point_set_pick_mode (sample_point,
                                       sample_point_undo->pick_mode);

      gimp_image_sample_point_moved (undo->image, sample_point);
    }

  sample_point_undo->x         = x;
  sample_point_undo->y         = y;
  sample_point_undo->pick_mode = pick_mode;
}
Ejemplo n.º 8
0
static void
gimp_image_rotate_sample_points (GimpImage        *image,
                                 GimpRotationType  rotate_type)
{
  GList *list;

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

      gimp_image_undo_push_sample_point (image, NULL, sample_point);

      gimp_sample_point_get_position (sample_point, &old_x, &old_y);

      switch (rotate_type)
        {
        case GIMP_ROTATE_90:
          gimp_sample_point_set_position (sample_point,
                                          gimp_image_get_height (image) - old_y,
                                          old_x);
          break;

        case GIMP_ROTATE_180:
          gimp_sample_point_set_position (sample_point,
                                          gimp_image_get_width  (image) - old_x,
                                          gimp_image_get_height (image) - old_y);
          break;

        case GIMP_ROTATE_270:
          gimp_sample_point_set_position (sample_point,
                                          old_y,
                                          gimp_image_get_width (image) - old_x);
          break;
        }
    }
}
static GimpValueArray *
image_get_sample_point_position_invoker (GimpProcedure         *procedure,
                                         Gimp                  *gimp,
                                         GimpContext           *context,
                                         GimpProgress          *progress,
                                         const GimpValueArray  *args,
                                         GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  GimpImage *image;
  gint32 sample_point;
  gint32 position_x = 0;
  gint32 position_y = 0;

  image = gimp_value_get_image (gimp_value_array_index (args, 0), gimp);
  sample_point = g_value_get_uint (gimp_value_array_index (args, 1));

  if (success)
    {
      GimpSamplePoint *sp = gimp_pdb_image_get_sample_point (image, sample_point,
                                                             error);

      if (sp)
        gimp_sample_point_get_position (sp, &position_x, &position_y);
      else
        success = FALSE;
    }

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

  if (success)
    {
      g_value_set_int (gimp_value_array_index (return_vals, 1), position_x);
      g_value_set_int (gimp_value_array_index (return_vals, 2), position_y);
    }

  return return_vals;
}
Ejemplo n.º 10
0
static void
gimp_sample_point_editor_proj_update (GimpImage             *image,
                                      gboolean               now,
                                      gint                   x,
                                      gint                   y,
                                      gint                   width,
                                      gint                   height,
                                      GimpSamplePointEditor *editor)
{
  GimpImageEditor *image_editor = GIMP_IMAGE_EDITOR (editor);
  GList           *sample_points;
  gint             n_points     = 0;
  GList           *list;
  gint             i;

  sample_points = gimp_image_get_sample_points (image_editor->image);

  n_points = MIN (4, g_list_length (sample_points));

  for (i = 0, list = sample_points;
       i < n_points;
       i++, list = g_list_next (list))
    {
      GimpSamplePoint *sample_point = list->data;
      gint             sp_x;
      gint             sp_y;

      gimp_sample_point_get_position (sample_point, &sp_x, &sp_y);

      if (sp_x >= x && sp_x < (x + width) &&
          sp_y >= y && sp_y < (y + height))
        {
          gimp_sample_point_editor_dirty (editor, i);
        }
    }
}
Ejemplo n.º 11
0
void
gimp_image_resize_with_layers (GimpImage    *image,
                               GimpContext  *context,
                               GimpFillType  fill_type,
                               gint          new_width,
                               gint          new_height,
                               gint          offset_x,
                               gint          offset_y,
                               GimpItemSet   layer_set,
                               gboolean      resize_text_layers,
                               GimpProgress *progress)
{
  GList   *list;
  GList   *resize_layers;
  gdouble  progress_max;
  gdouble  progress_current = 1.0;
  gint     old_width, old_height;

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

  g_object_freeze_notify (G_OBJECT (image));

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_RESIZE,
                               C_("undo-type", "Resize Image"));

  resize_layers = gimp_image_item_list_get_list (image,
                                                 GIMP_ITEM_TYPE_LAYERS,
                                                 layer_set);

  progress_max = (gimp_container_get_n_children (gimp_image_get_layers (image))   +
                  gimp_container_get_n_children (gimp_image_get_channels (image)) +
                  gimp_container_get_n_children (gimp_image_get_vectors (image))  +
                  g_list_length (resize_layers)                                   +
                  1 /* selection */);

  old_width  = gimp_image_get_width  (image);
  old_height = gimp_image_get_height (image);

  /*  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  */
  g_object_set (image,
                "width",  new_width,
                "height", new_height,
                NULL);

  /*  Resize all channels  */
  for (list = gimp_image_get_channel_iter (image);
       list;
       list = g_list_next (list))
    {
      GimpItem *item = list->data;

      gimp_item_resize (item, context, GIMP_FILL_TRANSPARENT,
                        new_width, new_height, offset_x, offset_y);

      if (progress)
        gimp_progress_set_value (progress, progress_current++ / progress_max);
    }

  /*  Resize all vectors  */
  for (list = gimp_image_get_vectors_iter (image);
       list;
       list = g_list_next (list))
    {
      GimpItem *item = list->data;

      gimp_item_resize (item, context, GIMP_FILL_TRANSPARENT,
                        new_width, new_height, offset_x, offset_y);

      if (progress)
        gimp_progress_set_value (progress, progress_current++ / progress_max);
    }

  /*  Don't forget the selection mask!  */
  gimp_item_resize (GIMP_ITEM (gimp_image_get_mask (image)),
                    context, GIMP_FILL_TRANSPARENT,
                    new_width, new_height, offset_x, offset_y);

  if (progress)
    gimp_progress_set_value (progress, progress_current++ / progress_max);

  /*  Reposition all layers  */
  for (list = gimp_image_get_layer_iter (image);
       list;
       list = g_list_next (list))
    {
      GimpItem *item = list->data;

      gimp_item_translate (item, offset_x, offset_y, TRUE);

      if (progress)
        gimp_progress_set_value (progress, progress_current++ / progress_max);
    }

  /*  Resize all resize_layers to image size  */
  for (list = resize_layers; list; list = g_list_next (list))
    {
      GimpItem *item = list->data;
      gint      old_offset_x;
      gint      old_offset_y;

      /*  group layers can't be resized here  */
      if (gimp_viewable_get_children (GIMP_VIEWABLE (item)))
        continue;

      if (! resize_text_layers && gimp_item_is_text_layer (item))
        continue;

      gimp_item_get_offset (item, &old_offset_x, &old_offset_y);

      gimp_item_resize (item, context, fill_type,
                        new_width, new_height,
                        old_offset_x, old_offset_y);

      if (progress)
        gimp_progress_set_value (progress, progress_current++ / progress_max);
    }

  g_list_free (resize_layers);

  /*  Reposition or remove all guides  */
  list = gimp_image_get_guides (image);

  while (list)
    {
      GimpGuide *guide        = list->data;
      gboolean   remove_guide = FALSE;
      gint       new_position = gimp_guide_get_position (guide);

      list = g_list_next (list);

      switch (gimp_guide_get_orientation (guide))
        {
        case GIMP_ORIENTATION_HORIZONTAL:
          new_position += offset_y;
          if (new_position < 0 || new_position > new_height)
            remove_guide = TRUE;
          break;

        case GIMP_ORIENTATION_VERTICAL:
          new_position += offset_x;
          if (new_position < 0 || new_position > new_width)
            remove_guide = TRUE;
          break;

        default:
          break;
        }

      if (remove_guide)
        gimp_image_remove_guide (image, guide, TRUE);
      else if (new_position != gimp_guide_get_position (guide))
        gimp_image_move_guide (image, guide, new_position, TRUE);
    }

  /*  Reposition or remove sample points  */
  list = gimp_image_get_sample_points (image);

  while (list)
    {
      GimpSamplePoint *sample_point        = list->data;
      gboolean         remove_sample_point = FALSE;
      gint             old_x;
      gint             old_y;
      gint             new_x;
      gint             new_y;

      list = g_list_next (list);

      gimp_sample_point_get_position (sample_point, &old_x, &old_y);

      new_y = old_y + offset_y;
      if ((new_y < 0) || (new_y > new_height))
        remove_sample_point = TRUE;

      new_x = old_x + offset_x;
      if ((new_x < 0) || (new_x > new_width))
        remove_sample_point = TRUE;

      if (remove_sample_point)
        gimp_image_remove_sample_point (image, sample_point, TRUE);
      else if (new_x != old_x || new_y != old_y)
        gimp_image_move_sample_point (image, sample_point,
                                      new_x, new_y, TRUE);
    }

  gimp_image_undo_group_end (image);

  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);
}
Ejemplo n.º 12
0
void
gimp_image_crop (GimpImage    *image,
                 GimpContext  *context,
                 GimpFillType  fill_type,
                 gint          x,
                 gint          y,
                 gint          width,
                 gint          height,
                 gboolean      crop_layers)
{
  GList *list;
  gint   previous_width;
  gint   previous_height;

  g_return_if_fail (GIMP_IS_IMAGE (image));
  g_return_if_fail (GIMP_IS_CONTEXT (context));

  previous_width  = gimp_image_get_width  (image);
  previous_height = gimp_image_get_height (image);

  /*  Make sure new width and height are non-zero  */
  if (width < 1 || height < 1)
    return;

  gimp_set_busy (image->gimp);

  g_object_freeze_notify (G_OBJECT (image));

  if (crop_layers)
    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CROP,
                                 C_("undo-type", "Crop Image"));
  else
    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_RESIZE,
                                 C_("undo-type", "Resize Image"));

  /*  Push the image size to the stack  */
  gimp_image_undo_push_image_size (image, NULL,
                                   x, y, width, height);

  /*  Set the new width and height  */
  g_object_set (image,
                "width",  width,
                "height", height,
                NULL);

  /*  Resize all channels  */
  for (list = gimp_image_get_channel_iter (image);
       list;
       list = g_list_next (list))
    {
      GimpItem *item = list->data;

      gimp_item_resize (item, context, GIMP_FILL_TRANSPARENT,
                        width, height, -x, -y);
    }

  /*  Resize all vectors  */
  for (list = gimp_image_get_vectors_iter (image);
       list;
       list = g_list_next (list))
    {
      GimpItem *item = list->data;

      gimp_item_resize (item, context, GIMP_FILL_TRANSPARENT,
                        width, height, -x, -y);
    }

  /*  Don't forget the selection mask!  */
  gimp_item_resize (GIMP_ITEM (gimp_image_get_mask (image)),
                    context, GIMP_FILL_TRANSPARENT,
                    width, height, -x, -y);

  /*  crop all layers  */
  list = gimp_image_get_layer_iter (image);

  while (list)
    {
      GimpItem *item = list->data;

      list = g_list_next (list);

      gimp_item_translate (item, -x, -y, TRUE);

      if (crop_layers)
        {
          gint off_x, off_y;
          gint lx1, ly1, lx2, ly2;

          gimp_item_get_offset (item, &off_x, &off_y);

          lx1 = CLAMP (off_x, 0, gimp_image_get_width  (image));
          ly1 = CLAMP (off_y, 0, gimp_image_get_height (image));
          lx2 = CLAMP (gimp_item_get_width  (item) + off_x,
                       0, gimp_image_get_width (image));
          ly2 = CLAMP (gimp_item_get_height (item) + off_y,
                       0, gimp_image_get_height (image));

          width  = lx2 - lx1;
          height = ly2 - ly1;

          if (width > 0 && height > 0)
            {
              gimp_item_resize (item, context, fill_type,
                                width, height,
                                -(lx1 - off_x),
                                -(ly1 - off_y));
            }
          else
            {
              gimp_image_remove_layer (image, GIMP_LAYER (item),
                                       TRUE, NULL);
            }
        }
    }

  /*  Reposition or remove guides  */
  list = gimp_image_get_guides (image);

  while (list)
    {
      GimpGuide *guide        = list->data;
      gboolean   remove_guide = FALSE;
      gint       position     = gimp_guide_get_position (guide);

      list = g_list_next (list);

      switch (gimp_guide_get_orientation (guide))
        {
        case GIMP_ORIENTATION_HORIZONTAL:
          position -= y;
          if ((position < 0) || (position > height))
            remove_guide = TRUE;
          break;

        case GIMP_ORIENTATION_VERTICAL:
          position -= x;
          if ((position < 0) || (position > width))
            remove_guide = TRUE;
          break;

        default:
          break;
        }

      if (remove_guide)
        gimp_image_remove_guide (image, guide, TRUE);
      else if (position != gimp_guide_get_position (guide))
        gimp_image_move_guide (image, guide, position, TRUE);
    }

  /*  Reposition or remove sample points  */
  list = gimp_image_get_sample_points (image);

  while (list)
    {
      GimpSamplePoint *sample_point        = list->data;
      gboolean         remove_sample_point = FALSE;
      gint             old_x;
      gint             old_y;
      gint             new_x;
      gint             new_y;

      list = g_list_next (list);

      gimp_sample_point_get_position (sample_point, &old_x, &old_y);
      new_x = old_x;
      new_y = old_y;

      new_y -= y;
      if ((new_y < 0) || (new_y > height))
       remove_sample_point = TRUE;

      new_x -= x;
      if ((new_x < 0) || (new_x > width))
        remove_sample_point = TRUE;

      if (remove_sample_point)
        gimp_image_remove_sample_point (image, sample_point, TRUE);
      else if (new_x != old_x || new_y != old_y)
        gimp_image_move_sample_point (image, sample_point,
                                      new_x, new_y, TRUE);
    }

  gimp_image_undo_group_end (image);

  gimp_image_size_changed_detailed (image,
                                    -x, -y,
                                    previous_width, previous_height);

  g_object_thaw_notify (G_OBJECT (image));

  gimp_unset_busy (image->gimp);
}
Ejemplo n.º 13
0
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;
      gint             x;
      gint             y;

      gimp_sample_point_get_position (sample_point, &x, &y);

      gimp_image_move_sample_point (image, sample_point,
                                    x * new_width  / old_width,
                                    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);
}
Ejemplo n.º 14
0
static void
gimp_sample_point_tool_start (GimpTool        *parent_tool,
                              GimpDisplay     *display,
                              GimpSamplePoint *sample_point)
{
  GimpSamplePointTool *sp_tool;
  GimpTool            *tool;

  sp_tool = g_object_new (GIMP_TYPE_SAMPLE_POINT_TOOL,
                          "tool-info", parent_tool->tool_info,
                          NULL);

  tool = GIMP_TOOL (sp_tool);

  gimp_display_shell_selection_pause (gimp_display_get_shell (display));

  if (sample_point)
    {
      sp_tool->sample_point = sample_point;

      gimp_sample_point_get_position (sample_point,
                                      &sp_tool->sample_point_old_x,
                                      &sp_tool->sample_point_old_y);

      sp_tool->sample_point_x = sp_tool->sample_point_old_x;
      sp_tool->sample_point_y = sp_tool->sample_point_old_y;
    }
  else
    {
      sp_tool->sample_point       = NULL;
      sp_tool->sample_point_old_x = 0;
      sp_tool->sample_point_old_y = 0;
      sp_tool->sample_point_x     = GIMP_SAMPLE_POINT_POSITION_UNDEFINED;
      sp_tool->sample_point_y     = GIMP_SAMPLE_POINT_POSITION_UNDEFINED;
    }

  gimp_tool_set_cursor (tool, display,
                        GIMP_CURSOR_MOUSE,
                        GIMP_TOOL_CURSOR_COLOR_PICKER,
                        GIMP_CURSOR_MODIFIER_MOVE);

  tool_manager_push_tool (display->gimp, tool);

  tool->display = display;
  gimp_tool_control_activate (tool->control);

  gimp_draw_tool_start (GIMP_DRAW_TOOL (sp_tool), display);

  if (sp_tool->sample_point)
    {
      gimp_tool_push_status_coords (tool, display,
                                    gimp_tool_control_get_precision (tool->control),
                                    _("Move Sample Point: "),
                                    sp_tool->sample_point_x -
                                    sp_tool->sample_point_old_x,
                                    ", ",
                                    sp_tool->sample_point_y -
                                    sp_tool->sample_point_old_y,
                                    NULL);
    }
  else
    {
      gimp_tool_push_status_coords (tool, display,
                                    gimp_tool_control_get_precision (tool->control),
                                    _("Add Sample Point: "),
                                    sp_tool->sample_point_x,
                                    ", ",
                                    sp_tool->sample_point_y,
                                    NULL);
    }
}