示例#1
0
gboolean
gimp_image_get_popup_size (GimpViewable *viewable,
                           gint          width,
                           gint          height,
                           gboolean      dot_for_dot,
                           gint         *popup_width,
                           gint         *popup_height)
{
  GimpImage *image = GIMP_IMAGE (viewable);

  if (gimp_image_get_width  (image) > width ||
      gimp_image_get_height (image) > height)
    {
      gboolean scaling_up;

      gimp_viewable_calc_preview_size (gimp_image_get_width  (image),
                                       gimp_image_get_height (image),
                                       width  * 2,
                                       height * 2,
                                       dot_for_dot, 1.0, 1.0,
                                       popup_width,
                                       popup_height,
                                       &scaling_up);

      if (scaling_up)
        {
          *popup_width  = gimp_image_get_width  (image);
          *popup_height = gimp_image_get_height (image);
        }

      return TRUE;
    }

  return FALSE;
}
示例#2
0
文件: grid-dialog.c 项目: 1ynx/gimp
static void
grid_dialog_response (GtkWidget  *widget,
                      gint        response_id,
                      GtkWidget  *dialog)
{
  GimpImage *image;
  GimpImage *grid;
  GimpGrid  *grid_backup;

  image       = g_object_get_data (G_OBJECT (dialog), "image");
  grid        = g_object_get_data (G_OBJECT (dialog), "grid");
  grid_backup = g_object_get_data (G_OBJECT (dialog), "grid-backup");

  switch (response_id)
    {
    case GRID_RESPONSE_RESET:
      gimp_config_sync (G_OBJECT (image->gimp->config->default_grid),
                        G_OBJECT (grid), 0);
      break;

    case GTK_RESPONSE_OK:
      if (! gimp_config_is_equal_to (GIMP_CONFIG (grid_backup),
                                     GIMP_CONFIG (grid)))
        {
          gimp_image_undo_push_image_grid (image, _("Grid"), grid_backup);
        }

      gtk_widget_destroy (dialog);
      break;

    default:
      gimp_image_set_grid (GIMP_IMAGE (image), grid_backup, FALSE);
      gtk_widget_destroy (dialog);
    }
}
示例#3
0
void
gimp_image_get_preview_size (GimpViewable *viewable,
                             gint          size,
                             gboolean      is_popup,
                             gboolean      dot_for_dot,
                             gint         *width,
                             gint         *height)
{
  GimpImage *image = GIMP_IMAGE (viewable);
  gdouble    xres;
  gdouble    yres;

  gimp_image_get_resolution (image, &xres, &yres);

  gimp_viewable_calc_preview_size (gimp_image_get_width  (image),
                                   gimp_image_get_height (image),
                                   size,
                                   size,
                                   dot_for_dot,
                                   xres,
                                   yres,
                                   width,
                                   height,
                                   NULL);
}
示例#4
0
static void
image_scale_callback (GtkWidget              *dialog,
                      GimpViewable           *viewable,
                      gint                    width,
                      gint                    height,
                      GimpUnit                unit,
                      GimpInterpolationType   interpolation,
                      gdouble                 xresolution,
                      gdouble                 yresolution,
                      GimpUnit                resolution_unit,
                      gpointer                user_data)
{
  GimpImage *image = GIMP_IMAGE (viewable);
  gdouble    xres;
  gdouble    yres;

  image_scale_unit   = unit;
  image_scale_interp = interpolation;

  gimp_image_get_resolution (image, &xres, &yres);

  if (width > 0 && height > 0)
    {
      if (width           == gimp_image_get_width  (image) &&
          height          == gimp_image_get_height (image) &&
          xresolution     == xres                          &&
          yresolution     == yres                          &&
          resolution_unit == gimp_image_get_unit (image))
        return;

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_SCALE,
                                   _("Scale Image"));

      gimp_image_set_resolution (image, xresolution, yresolution);
      gimp_image_set_unit (image, resolution_unit);

      if (width  != gimp_image_get_width  (image) ||
          height != gimp_image_get_height (image))
        {
          GimpProgress *progress;

          progress = gimp_progress_start (GIMP_PROGRESS (user_data),
                                          _("Scaling"), FALSE);

          gimp_image_scale (image, width, height, interpolation, progress);

          if (progress)
            gimp_progress_end (progress);
        }

      gimp_image_undo_group_end (image);

      gimp_image_flush (image);
    }
  else
    {
      g_warning ("Scale Error: "
                 "Both width and height must be greater than zero.");
    }
}
示例#5
0
static void
select_feather_callback (GtkWidget *widget,
                         gdouble    size,
                         GimpUnit   unit,
                         gpointer   data)
{
  GimpImage *image = GIMP_IMAGE (data);
  gdouble    radius_x;
  gdouble    radius_y;

  radius_x = radius_y = select_feather_radius = size;

  if (unit != GIMP_UNIT_PIXEL)
    {
      gdouble xres;
      gdouble yres;
      gdouble factor;

      gimp_image_get_resolution (image, &xres, &yres);

      factor = (MAX (xres, yres) /
                MIN (xres, yres));

      if (xres == MIN (xres, yres))
        radius_y *= factor;
      else
        radius_x *= factor;
    }

  gimp_channel_feather (gimp_image_get_mask (image), radius_x, radius_y, TRUE);
  gimp_image_flush (image);
}
示例#6
0
static void
select_grow_callback (GtkWidget *widget,
                      gdouble    size,
                      GimpUnit   unit,
                      gpointer   data)
{
  GimpImage *image = GIMP_IMAGE (data);
  gdouble    radius_x;
  gdouble    radius_y;

  radius_x = radius_y = select_grow_pixels = ROUND (size);

  if (unit != GIMP_UNIT_PIXEL)
    {
      gdouble factor;

      factor = (MAX (image->xresolution, image->yresolution) /
                MIN (image->xresolution, image->yresolution));

      if (image->xresolution == MIN (image->xresolution, image->yresolution))
        radius_y *= factor;
      else
        radius_x *= factor;
    }

  gimp_channel_grow (gimp_image_get_mask (image), radius_x, radius_y, TRUE);
  gimp_image_flush (image);
}
示例#7
0
static void
select_shrink_callback (GtkWidget *widget,
                        gdouble    size,
                        GimpUnit   unit,
                        gpointer   data)
{
  GimpImage *image  = GIMP_IMAGE (data);
  GtkWidget *button = g_object_get_data (G_OBJECT (widget), "edge-lock-toggle");
  gint       radius_x;
  gint       radius_y;

  radius_x = radius_y = select_shrink_pixels = ROUND (size);

  select_shrink_edge_lock =
    ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));

  if (unit != GIMP_UNIT_PIXEL)
    {
      gdouble factor;

      factor = (MAX (image->xresolution, image->yresolution) /
                MIN (image->xresolution, image->yresolution));

      if (image->xresolution == MIN (image->xresolution, image->yresolution))
        radius_y *= factor;
      else
        radius_x *= factor;
    }

  gimp_channel_shrink (gimp_image_get_mask (image), radius_x, radius_y,
                       select_shrink_edge_lock, TRUE);
  gimp_image_flush (image);
}
示例#8
0
static gboolean
windows_menu_display_query_tooltip (GtkWidget  *widget,
                                    gint        x,
                                    gint        y,
                                    gboolean    keyboard_mode,
                                    GtkTooltip *tooltip,
                                    GimpAction *action)
{
  GimpImage *image = GIMP_IMAGE (action->viewable);
  gchar     *text;
  gdouble    xres;
  gdouble    yres;
  gint       width;
  gint       height;

  text = gtk_widget_get_tooltip_text (widget);
  gtk_tooltip_set_text (tooltip, text);
  g_free (text);

  gimp_image_get_resolution (image, &xres, &yres);

  gimp_viewable_calc_preview_size (gimp_image_get_width  (image),
                                   gimp_image_get_height (image),
                                   GIMP_VIEW_SIZE_HUGE, GIMP_VIEW_SIZE_HUGE,
                                   FALSE, xres, yres,
                                   &width, &height, NULL);

  gtk_tooltip_set_icon (tooltip,
                        gimp_viewable_get_pixbuf (action->viewable,
                                                  action->context,
                                                  width, height));

  return TRUE;
}
示例#9
0
GimpTempBuf *
gimp_image_get_new_preview (GimpViewable *viewable,
                            GimpContext  *context,
                            gint          width,
                            gint          height)
{
  GimpImage   *image = GIMP_IMAGE (viewable);
  const Babl  *format;
  gboolean     linear;
  GimpTempBuf *buf;
  gdouble      scale_x;
  gdouble      scale_y;

  scale_x = (gdouble) width  / (gdouble) gimp_image_get_width  (image);
  scale_y = (gdouble) height / (gdouble) gimp_image_get_height (image);

  format = gimp_projectable_get_format (GIMP_PROJECTABLE (image));
  linear = gimp_babl_format_get_linear (format);

  format = gimp_babl_format (gimp_babl_format_get_base_type (format),
                             gimp_babl_precision (GIMP_COMPONENT_TYPE_U8,
                                                  linear),
                             babl_format_has_alpha (format));

  buf = gimp_temp_buf_new (width, height, format);

  gegl_buffer_get (gimp_pickable_get_buffer (GIMP_PICKABLE (image)),
                   GEGL_RECTANGLE (0, 0, width, height),
                   MIN (scale_x, scale_y),
                   gimp_temp_buf_get_format (buf),
                   gimp_temp_buf_get_data (buf),
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);

  return buf;
}
示例#10
0
static void
copy_named_buffer_callback (GtkWidget   *widget,
                            const gchar *name,
                            gpointer     data)
{
  GimpImage    *image    = GIMP_IMAGE (data);
  GimpDrawable *drawable = gimp_image_get_active_drawable (image);
  GError       *error    = NULL;

  if (! drawable)
    {
      gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_WARNING,
			    _("There is no active layer or channel to copy from."));
      return;
    }

  if (! (name && strlen (name)))
    name = _("(Unnamed Buffer)");

  if (gimp_edit_named_copy (image, name, drawable,
                            gimp_get_user_context (image->gimp), &error))
    {
      gimp_image_flush (image);
    }
  else
    {
      gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_WARNING,
			    error->message);
      g_clear_error (&error);
    }
}
static void
image_preview_drop_image (GtkWidget    *widget,
                          gint          x,
                          gint          y,
                          GimpViewable *viewable,
                          gpointer      data)
{
  GimpContext *context = GIMP_CONTEXT (data);

  gimp_context_set_image (context, GIMP_IMAGE (viewable));
}
示例#12
0
static void
image_resize_callback (GtkWidget    *dialog,
                       GimpViewable *viewable,
                       gint          width,
                       gint          height,
                       GimpUnit      unit,
                       gint          offset_x,
                       gint          offset_y,
                       GimpItemSet   layer_set,
                       gpointer      data)
{
  ImageResizeOptions *options = data;

  image_resize_unit = unit;

  if (width > 0 && height > 0)
    {
      GimpImage    *image   = GIMP_IMAGE (viewable);
      GimpDisplay  *display = options->display;
      GimpContext  *context = options->context;
      GimpProgress *progress;

      gtk_widget_destroy (dialog);

      if (width  == gimp_image_get_width  (image) &&
          height == gimp_image_get_height (image))
        return;

      progress = gimp_progress_start (GIMP_PROGRESS (display),
                                      _("Resizing"), FALSE);

      gimp_image_resize_with_layers (image,
                                     context,
                                     width, height, offset_x, offset_y,
                                     layer_set,
                                     progress);

      if (progress)
        gimp_progress_end (progress);

      gimp_image_flush (image);
    }
  else
    {
      g_warning ("Resize Error: "
                 "Both width and height must be greater than zero.");
    }
}
示例#13
0
static void
select_border_callback (GtkWidget *widget,
                        gdouble    size,
                        GimpUnit   unit,
                        gpointer   data)
{
  GimpImage *image  = GIMP_IMAGE (data);
  GtkWidget *feather_button = g_object_get_data (G_OBJECT (widget),
                                                 "border-feather-toggle");
  GtkWidget *edge_lock_button = g_object_get_data (G_OBJECT (widget),
                                                   "edge-lock-toggle");
  gdouble    radius_x;
  gdouble    radius_y;

  radius_x = radius_y = select_border_radius = ROUND (size);

  select_border_feather =
    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (feather_button));

  select_border_edge_lock =
    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (edge_lock_button));

  if (unit != GIMP_UNIT_PIXEL)
    {
      gdouble xres;
      gdouble yres;
      gdouble factor;

      gimp_image_get_resolution (image, &xres, &yres);

      factor = (MAX (xres, yres) /
                MIN (xres, yres));

      if (xres == MIN (xres, yres))
        radius_y *= factor;
      else
        radius_x *= factor;
    }

  gimp_channel_border (gimp_image_get_mask (image), radius_x, radius_y,
                       select_border_feather, select_border_edge_lock, TRUE);
  gimp_image_flush (image);
}
示例#14
0
GimpImage *
gimp_edit_paste_as_new_image (Gimp       *gimp,
                              GimpObject *paste)
{
  GimpImage *image = NULL;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (GIMP_IS_IMAGE (paste) || GIMP_IS_BUFFER (paste), NULL);

  if (GIMP_IS_IMAGE (paste))
    {
      image = gimp_image_duplicate (GIMP_IMAGE (paste));
    }
  else if (GIMP_IS_BUFFER (paste))
    {
      image = gimp_image_new_from_buffer (gimp, GIMP_BUFFER (paste));
    }

  return image;
}
示例#15
0
static void
copy_named_visible_buffer_callback (GtkWidget   *widget,
                                    const gchar *name,
                                    gpointer     data)
{
  GimpImage *image = GIMP_IMAGE (data);
  GError    *error = NULL;

  if (! (name && strlen (name)))
    name = _("(Unnamed Buffer)");

  if (gimp_edit_named_copy_visible (image, name,
                                    gimp_get_user_context (image->gimp),
                                    &error))
    {
      gimp_image_flush (image);
    }
  else
    {
      gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_WARNING,
			    error->message);
      g_clear_error (&error);
    }
}
static void
palette_import_image_callback (GtkWidget    *widget,
                               ImportDialog *dialog)
{
  GimpImage *image;

  if (! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
    return;

  dialog->import_type = IMAGE_IMPORT;

  image = gimp_context_get_image (dialog->context);

  if (! image)
    {
      GimpContainer *images = dialog->context->gimp->images;

      image = GIMP_IMAGE (gimp_container_get_first_child (images));
    }

  palette_import_set_sensitive (dialog);

  palette_import_image_changed (dialog->context, image, dialog);
}
示例#17
0
GdkPixbuf *
gimp_image_get_new_pixbuf (GimpViewable *viewable,
                           GimpContext  *context,
                           gint          width,
                           gint          height)
{
  GimpImage          *image = GIMP_IMAGE (viewable);
  GdkPixbuf          *pixbuf;
  gdouble             scale_x;
  gdouble             scale_y;
  GimpColorTransform *transform;

  scale_x = (gdouble) width  / (gdouble) gimp_image_get_width  (image);
  scale_y = (gdouble) height / (gdouble) gimp_image_get_height (image);

  pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
                           width, height);

  transform = gimp_image_get_color_transform_to_srgb_u8 (image);

  if (transform)
    {
      GimpTempBuf *temp_buf;
      GeglBuffer  *src_buf;
      GeglBuffer  *dest_buf;

      temp_buf = gimp_temp_buf_new (width, height,
                                    gimp_pickable_get_format (GIMP_PICKABLE (image)));

      gegl_buffer_get (gimp_pickable_get_buffer (GIMP_PICKABLE (image)),
                       GEGL_RECTANGLE (0, 0, width, height),
                       MIN (scale_x, scale_y),
                       gimp_temp_buf_get_format (temp_buf),
                       gimp_temp_buf_get_data (temp_buf),
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);

      src_buf  = gimp_temp_buf_create_buffer (temp_buf);
      dest_buf = gimp_pixbuf_create_buffer (pixbuf);

      gimp_temp_buf_unref (temp_buf);

      gimp_color_transform_process_buffer (transform,
                                           src_buf,
                                           GEGL_RECTANGLE (0, 0,
                                                           width, height),
                                           dest_buf,
                                           GEGL_RECTANGLE (0, 0, 0, 0));

      g_object_unref (src_buf);
      g_object_unref (dest_buf);
    }
  else
    {
      gegl_buffer_get (gimp_pickable_get_buffer (GIMP_PICKABLE (image)),
                       GEGL_RECTANGLE (0, 0, width, height),
                       MIN (scale_x, scale_y),
                       gimp_pixbuf_get_format (pixbuf),
                       gdk_pixbuf_get_pixels (pixbuf),
                       gdk_pixbuf_get_rowstride (pixbuf),
                       GEGL_ABYSS_CLAMP);
    }

  return pixbuf;
}
示例#18
0
GtkWidget *
resize_dialog_new (GimpViewable       *viewable,
                   GimpContext        *context,
                   const gchar        *title,
                   const gchar        *role,
                   GtkWidget          *parent,
                   GimpHelpFunc        help_func,
                   const gchar        *help_id,
                   GimpUnit            unit,
                   GimpResizeCallback  callback,
                   gpointer            user_data)
{
  GtkWidget    *dialog;
  GtkWidget    *main_vbox;
  GtkWidget    *vbox;
  GtkWidget    *abox;
  GtkWidget    *frame;
  GtkWidget    *button;
  GtkWidget    *spinbutton;
  GtkWidget    *entry;
  GtkObject    *adjustment;
  GdkPixbuf    *pixbuf;
  ResizeDialog *private;
  GimpImage    *image = NULL;
  const gchar  *text  = NULL;
  gint          width, height;
  gdouble       xres, yres;

  g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (callback != NULL, NULL);

  if (GIMP_IS_IMAGE (viewable))
    {
      image = GIMP_IMAGE (viewable);

      width  = gimp_image_get_width (image);
      height = gimp_image_get_height (image);

      text = _("Canvas Size");
    }
  else if (GIMP_IS_ITEM (viewable))
    {
      GimpItem *item = GIMP_ITEM (viewable);

      image = gimp_item_get_image (item);

      width  = gimp_item_width (item);
      height = gimp_item_height (item);

      text = _("Layer Size");
    }
  else
    {
      g_return_val_if_reached (NULL);
    }

  dialog = gimp_viewable_dialog_new (viewable, context,
                                     title, role, GIMP_STOCK_RESIZE, title,
                                     parent,
                                     help_func, help_id,

                                     GIMP_STOCK_RESET,  RESPONSE_RESET,
                                     GTK_STOCK_CANCEL,  GTK_RESPONSE_CANCEL,
                                     GIMP_STOCK_RESIZE, GTK_RESPONSE_OK,

                                     NULL);

  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);

  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           RESPONSE_RESET,
                                           GTK_RESPONSE_OK,
                                           GTK_RESPONSE_CANCEL,
                                           -1);

  private = g_slice_new0 (ResizeDialog);
示例#19
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));
}
示例#20
0
GimpLayer *
gimp_edit_paste (GimpImage     *image,
                 GimpDrawable  *drawable,
                 GimpObject    *paste,
                 GimpPasteType  paste_type,
                 gint           viewport_x,
                 gint           viewport_y,
                 gint           viewport_width,
                 gint           viewport_height)
{
  GimpLayer  *layer = NULL;
  const Babl *floating_format;
  gint        offset_x;
  gint        offset_y;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable), NULL);
  g_return_val_if_fail (drawable == NULL ||
                        gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
  g_return_val_if_fail (GIMP_IS_IMAGE (paste) || GIMP_IS_BUFFER (paste), NULL);

  /*  change paste type to NEW_LAYER for cases where we can't attach a
   *  floating selection
   */
  if (! drawable                                            ||
      gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) ||
      gimp_item_is_content_locked (GIMP_ITEM (drawable)))
    {
      paste_type = GIMP_PASTE_TYPE_NEW_LAYER;
    }

  /*  floating pastes always have the pasted-to drawable's format with
   *  alpha; if drawable == NULL, user is pasting into an empty image
   */
  if (drawable)
    floating_format = gimp_drawable_get_format_with_alpha (drawable);
  else
    floating_format = gimp_image_get_layer_format (image, TRUE);

  if (GIMP_IS_IMAGE (paste))
    {
      GType layer_type;

      layer = gimp_image_get_layer_iter (GIMP_IMAGE (paste))->data;

      switch (paste_type)
        {
        case GIMP_PASTE_TYPE_FLOATING:
        case GIMP_PASTE_TYPE_FLOATING_INTO:
          /*  when pasting as floating selection, force creation of a
           *  plain layer, so gimp_item_convert() will collapse a
           *  group layer
           */
          layer_type = GIMP_TYPE_LAYER;
          break;

        case GIMP_PASTE_TYPE_NEW_LAYER:
          layer_type = G_TYPE_FROM_INSTANCE (layer);
          break;

        default:
          g_return_val_if_reached (NULL);
        }

      layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (layer),
                                             image, layer_type));

      switch (paste_type)
        {
        case GIMP_PASTE_TYPE_FLOATING:
        case GIMP_PASTE_TYPE_FLOATING_INTO:
          /*  when pasting as floating selection, get rid of the layer mask,
           *  and make sure the layer has the right format
           */
          if (gimp_layer_get_mask (layer))
            gimp_layer_apply_mask (layer, GIMP_MASK_DISCARD, FALSE);

          if (gimp_drawable_get_format (GIMP_DRAWABLE (layer)) !=
              floating_format)
            {
              gimp_drawable_convert_type (GIMP_DRAWABLE (layer), image,
                                          gimp_drawable_get_base_type (drawable),
                                          gimp_drawable_get_precision (drawable),
                                          TRUE,
                                          NULL,
                                          GEGL_DITHER_NONE, GEGL_DITHER_NONE,
                                          FALSE, NULL);
            }
          break;

        default:
          break;
        }
    }
  else if (GIMP_IS_BUFFER (paste))
    {
      layer = gimp_layer_new_from_buffer (GIMP_BUFFER (paste), image,
                                          floating_format,
                                          _("Pasted Layer"),
                                          GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
    }

  if (! layer)
    return NULL;

  gimp_edit_get_paste_offset (image, drawable, GIMP_OBJECT (layer),
                              viewport_x,
                              viewport_y,
                              viewport_width,
                              viewport_height,
                              &offset_x,
                              &offset_y);
  gimp_item_set_offset (GIMP_ITEM (layer), offset_x, offset_y);

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                               C_("undo-type", "Paste"));

  switch (paste_type)
    {
    case GIMP_PASTE_TYPE_FLOATING:
      /*  if there is a selection mask clear it - this might not
       *  always be desired, but in general, it seems like the correct
       *  behavior
       */
      if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
        gimp_channel_clear (gimp_image_get_mask (image), NULL, TRUE);

      /* fall thru */

    case GIMP_PASTE_TYPE_FLOATING_INTO:
      floating_sel_attach (layer, drawable);
      break;

    case GIMP_PASTE_TYPE_NEW_LAYER:
      {
        GimpLayer *parent   = NULL;
        gint       position = 0;

        /* always add on top of the passed layer, where we would
         * attach a floating selection
         */
        if (GIMP_IS_LAYER (drawable))
          {
            parent   = gimp_layer_get_parent (GIMP_LAYER (drawable));
            position = gimp_item_get_index (GIMP_ITEM (drawable));
          }

        gimp_image_add_layer (image, layer, parent, position, TRUE);
      }
      break;
    }

  gimp_image_undo_group_end (image);

  return layer;
}
示例#21
0
文件: grid-dialog.c 项目: 1ynx/gimp
GtkWidget *
grid_dialog_new (GimpImage   *image,
                 GimpContext *context,
                 GtkWidget   *parent)
{
  GimpGrid  *grid;
  GimpGrid  *grid_backup;
  GtkWidget *dialog;
  GtkWidget *editor;
  gdouble    xres;
  gdouble    yres;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (parent == NULL || GTK_IS_WIDGET (parent), NULL);

  gimp_image_get_resolution (image, &xres, &yres);

  grid = gimp_image_get_grid (GIMP_IMAGE (image));
  grid_backup = gimp_config_duplicate (GIMP_CONFIG (grid));

  dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context,
                                     _("Configure Grid"), "gimp-grid-configure",
                                     GIMP_STOCK_GRID, _("Configure Image Grid"),
                                     parent,
                                     gimp_standard_help_func,
                                     GIMP_HELP_IMAGE_GRID,

                                     GIMP_STOCK_RESET, GRID_RESPONSE_RESET,
                                     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                     GTK_STOCK_OK,     GTK_RESPONSE_OK,

                                     NULL);

  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);

  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           GRID_RESPONSE_RESET,
                                           GTK_RESPONSE_OK,
                                           GTK_RESPONSE_CANCEL,
                                           -1);

  g_signal_connect (dialog, "response",
                    G_CALLBACK (grid_dialog_response),
                    dialog);

  editor = gimp_grid_editor_new (grid, context, xres, yres);
  gtk_container_set_border_width (GTK_CONTAINER (editor), 12);
  gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
                      editor, TRUE, TRUE, 0);

  gtk_widget_show (editor);

  g_object_set_data (G_OBJECT (dialog), "image", image);
  g_object_set_data (G_OBJECT (dialog), "grid", grid);

  g_object_set_data_full (G_OBJECT (dialog), "grid-backup", grid_backup,
                          (GDestroyNotify) g_object_unref);

  return dialog;
}
示例#22
0
static void
image_scale_callback (GtkWidget             *widget,
                      GimpViewable          *viewable,
                      gint                   width,
                      gint                   height,
                      GimpUnit               unit,
                      GimpInterpolationType  interpolation,
                      gdouble                xresolution,
                      gdouble                yresolution,
                      GimpUnit               resolution_unit,
                      gpointer               data)
{
  ImageScaleDialog        *dialog = data;
  GimpImage               *image  = GIMP_IMAGE (viewable);
  GimpImageScaleCheckType  scale_check;
  gint64                   max_memsize;
  gint64                   new_memsize;

  dialog->width           = width;
  dialog->height          = height;
  dialog->unit            = unit;
  dialog->interpolation   = interpolation;
  dialog->xresolution     = xresolution;
  dialog->yresolution     = yresolution;
  dialog->resolution_unit = resolution_unit;

  gtk_widget_set_sensitive (widget, FALSE);

  max_memsize = GIMP_GUI_CONFIG (image->gimp->config)->max_new_image_size;

  scale_check = gimp_image_scale_check (image,
                                        width, height, max_memsize,
                                        &new_memsize);
  switch (scale_check)
    {
    case GIMP_IMAGE_SCALE_TOO_BIG:
      image_scale_confirm_large (dialog, new_memsize, max_memsize);
      break;

    case GIMP_IMAGE_SCALE_TOO_SMALL:
      image_scale_confirm_small (dialog);
      break;

    case GIMP_IMAGE_SCALE_OK:
      gtk_widget_hide (widget);
      dialog->callback (dialog->dialog,
                        GIMP_VIEWABLE (dialog->image),
                        dialog->width,
                        dialog->height,
                        dialog->unit,
                        dialog->interpolation,
                        dialog->xresolution,
                        dialog->yresolution,
                        dialog->resolution_unit,
                        dialog->user_data);
      gtk_widget_destroy (widget);

      /* remember the last used unit */
      g_object_set_data (G_OBJECT (image),
                         "scale-dialog-unit", GINT_TO_POINTER (unit));
      break;
    }
}
static void
gimp_view_renderer_image_render (GimpViewRenderer *renderer,
                                 GtkWidget        *widget)
{
  GimpViewRendererImage *rendererimage = GIMP_VIEW_RENDERER_IMAGE (renderer);
  GimpImage             *image         = GIMP_IMAGE (renderer->viewable);
  const gchar           *icon_name;

  /* The conditions checked here are mostly a hack to hide the fact that
   * we are creating the channel preview from the image preview and turning
   * off visibility of a channel has the side-effect of painting the channel
   * preview all black. See bug #459518 for details.
   */
  if (rendererimage->channel == -1 ||
      (gimp_image_get_component_visible (image, rendererimage->channel) &&
       gimp_image_get_component_visible (image, GIMP_ALPHA_CHANNEL)))
    {
      gint         view_width;
      gint         view_height;
      gdouble      xres;
      gdouble      yres;
      gboolean     scaling_up;
      GimpTempBuf *render_buf = NULL;

      gimp_image_get_resolution (image, &xres, &yres);

      gimp_viewable_calc_preview_size (gimp_image_get_width  (image),
                                       gimp_image_get_height (image),
                                       renderer->width,
                                       renderer->height,
                                       renderer->dot_for_dot,
                                       xres,
                                       yres,
                                       &view_width,
                                       &view_height,
                                       &scaling_up);

      if (scaling_up)
        {
          GimpTempBuf *temp_buf;

          temp_buf = gimp_viewable_get_new_preview (renderer->viewable,
                                                    renderer->context,
                                                    gimp_image_get_width  (image),
                                                    gimp_image_get_height (image));

          if (temp_buf)
            {
              render_buf = gimp_temp_buf_scale (temp_buf,
                                                view_width, view_height);
              gimp_temp_buf_unref (temp_buf);
            }
        }
      else
        {
          render_buf = gimp_viewable_get_new_preview (renderer->viewable,
                                                      renderer->context,
                                                      view_width,
                                                      view_height);
        }

      if (render_buf)
        {
          gint render_buf_x    = 0;
          gint render_buf_y    = 0;
          gint component_index = -1;

          /*  xresolution != yresolution */
          if (view_width > renderer->width || view_height > renderer->height)
            {
              GimpTempBuf *temp_buf;

              temp_buf = gimp_temp_buf_scale (render_buf,
                                              renderer->width, renderer->height);
              gimp_temp_buf_unref (render_buf);
              render_buf = temp_buf;
            }

          if (view_width  < renderer->width)
            render_buf_x = (renderer->width  - view_width)  / 2;

          if (view_height < renderer->height)
            render_buf_y = (renderer->height - view_height) / 2;

          if (rendererimage->channel != -1)
            component_index =
              gimp_image_get_component_index (image, rendererimage->channel);

          gimp_view_renderer_render_temp_buf (renderer, widget, render_buf,
                                              render_buf_x, render_buf_y,
                                              component_index,
                                              GIMP_VIEW_BG_CHECKS,
                                              GIMP_VIEW_BG_WHITE);
          gimp_temp_buf_unref (render_buf);

          return;
        }
    }

  switch (rendererimage->channel)
    {
    case GIMP_RED_CHANNEL:     icon_name = GIMP_STOCK_CHANNEL_RED;     break;
    case GIMP_GREEN_CHANNEL:   icon_name = GIMP_STOCK_CHANNEL_GREEN;   break;
    case GIMP_BLUE_CHANNEL:    icon_name = GIMP_STOCK_CHANNEL_BLUE;    break;
    case GIMP_GRAY_CHANNEL:    icon_name = GIMP_STOCK_CHANNEL_GRAY;    break;
    case GIMP_INDEXED_CHANNEL: icon_name = GIMP_STOCK_CHANNEL_INDEXED; break;
    case GIMP_ALPHA_CHANNEL:   icon_name = GIMP_STOCK_CHANNEL_ALPHA;   break;

    default:
      icon_name = gimp_viewable_get_icon_name (renderer->viewable);
      break;
    }

  gimp_view_renderer_render_icon (renderer, widget, icon_name);
}