예제 #1
0
static void
gimp_display_shell_drop_buffer (GtkWidget    *widget,
                                gint          drop_x,
                                gint          drop_y,
                                GimpViewable *viewable,
                                gpointer      data)
{
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image = gimp_display_get_image (shell->display);
  GimpDrawable     *drawable;
  GimpBuffer       *buffer;
  gint              x, y, width, height;

  GIMP_LOG (DND, NULL);

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

  if (! image)
    {
      image = gimp_image_new_from_buffer (shell->display->gimp, NULL,
                                          GIMP_BUFFER (viewable));
      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0);
      g_object_unref (image);

      return;
    }

  drawable = gimp_image_get_active_drawable (image);

  if (drawable)
    {
      if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
        {
          gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
                                GIMP_MESSAGE_ERROR,
                                _("Cannot modify the pixels of layer groups."));
          return;
        }

      if (gimp_item_is_content_locked (GIMP_ITEM (drawable)))
        {
          gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
                                GIMP_MESSAGE_ERROR,
                                _("The active layer's pixels are locked."));
          return;
        }
    }

  buffer = GIMP_BUFFER (viewable);

  gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height);

  /* FIXME: popup a menu for selecting "Paste Into" */

  gimp_edit_paste (image, drawable, buffer, FALSE,
                   x, y, width, height);

  gimp_display_shell_dnd_flush (shell, image);
}
예제 #2
0
static void
gimp_display_shell_drop_buffer (GtkWidget    *widget,
                                gint          drop_x,
                                gint          drop_y,
                                GimpViewable *viewable,
                                gpointer      data)
{
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image = shell->display->image;
  GimpBuffer       *buffer;
  gint              x, y, width, height;

  GIMP_LOG (DND, NULL);

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

  if (! image)
    return;

  buffer = GIMP_BUFFER (viewable);

  gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height);

  /* FIXME: popup a menu for selecting "Paste Into" */

  gimp_edit_paste (image, gimp_image_get_active_drawable (image),
                   buffer, FALSE,
                   x, y, width, height);

  gimp_display_shell_dnd_flush (shell, image);
}
예제 #3
0
static GimpTempBuf *
gimp_buffer_get_new_preview (GimpViewable *viewable,
                             GimpContext  *context,
                             gint          width,
                             gint          height)
{
  GimpBuffer  *buffer = GIMP_BUFFER (viewable);
  const Babl  *format = gimp_buffer_get_format (buffer);
  GimpTempBuf *preview;

  if (babl_format_is_palette (format))
    format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8_GAMMA,
                               babl_format_has_alpha (format));
  else
    format = gimp_babl_format (gimp_babl_format_get_base_type (format),
                               gimp_babl_precision (GIMP_COMPONENT_TYPE_U8,
                                                    gimp_babl_format_get_linear (format)),
                               babl_format_has_alpha (format));

  preview = gimp_temp_buf_new (width, height, format);

  gegl_buffer_get (buffer->buffer, GEGL_RECTANGLE (0, 0, width, height),
                   MIN ((gdouble) width  / (gdouble) gimp_buffer_get_width (buffer),
                        (gdouble) height / (gdouble) gimp_buffer_get_height (buffer)),
                   format,
                   gimp_temp_buf_get_data (preview),
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  return preview;
}
예제 #4
0
static TempBuf *
gimp_buffer_get_new_preview (GimpViewable *viewable,
                             GimpContext  *context,
                             gint          width,
                             gint          height)
{
  GimpBuffer *buffer = GIMP_BUFFER (viewable);

  return tile_manager_get_preview (buffer->tiles, width, height);
}
예제 #5
0
static GimpColorProfile *
gimp_buffer_color_managed_get_color_profile (GimpColorManaged *managed)
{
  GimpBuffer *buffer = GIMP_BUFFER (managed);

  if (buffer->color_profile)
    return buffer->color_profile;

  return gimp_babl_format_get_color_profile (gimp_buffer_get_format (buffer));
}
예제 #6
0
static void
gimp_buffer_finalize (GObject *object)
{
  GimpBuffer *buffer = GIMP_BUFFER (object);

  g_clear_object (&buffer->buffer);

  gimp_buffer_set_color_profile (buffer, NULL);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
예제 #7
0
static gchar *
gimp_buffer_get_description (GimpViewable  *viewable,
                             gchar        **tooltip)
{
  GimpBuffer *buffer = GIMP_BUFFER (viewable);

  return g_strdup_printf ("%s (%d × %d)",
                          GIMP_OBJECT (buffer)->name,
                          gimp_buffer_get_width (buffer),
                          gimp_buffer_get_height (buffer));
}
예제 #8
0
static const guint8 *
gimp_buffer_color_managed_get_icc_profile (GimpColorManaged *managed,
                             gsize            *len)
{
  GimpBuffer *buffer = GIMP_BUFFER (managed);

  if (buffer->color_profile)
    return gimp_color_profile_get_icc_profile (buffer->color_profile, len);

  return NULL;
}
예제 #9
0
static gboolean
gimp_buffer_get_size (GimpViewable *viewable,
                      gint         *width,
                      gint         *height)
{
  GimpBuffer *buffer = GIMP_BUFFER (viewable);

  *width  = gimp_buffer_get_width (buffer);
  *height = gimp_buffer_get_height (buffer);

  return TRUE;
}
예제 #10
0
static gint64
gimp_buffer_get_memsize (GimpObject *object,
                         gint64     *gui_size)
{
  GimpBuffer *buffer  = GIMP_BUFFER (object);
  gint64      memsize = 0;

  memsize += gimp_gegl_buffer_get_memsize (buffer->buffer);

  return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
                                                                  gui_size);
}
예제 #11
0
static void
gimp_buffer_finalize (GObject *object)
{
  GimpBuffer *buffer = GIMP_BUFFER (object);

  if (buffer->buffer)
    {
      g_object_unref (buffer->buffer);
      buffer->buffer = NULL;
    }

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
예제 #12
0
static void
gimp_buffer_finalize (GObject *object)
{
  GimpBuffer *buffer = GIMP_BUFFER (object);

  if (buffer->tiles)
    {
      tile_manager_unref (buffer->tiles);
      buffer->tiles = NULL;
    }

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
예제 #13
0
static gint64
gimp_buffer_get_memsize (GimpObject *object,
                         gint64     *gui_size)
{
  GimpBuffer *buffer  = GIMP_BUFFER (object);
  gint64      memsize = 0;

  if (buffer->tiles)
    memsize += tile_manager_get_memsize (buffer->tiles, FALSE);

  return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
                                                                  gui_size);
}
예제 #14
0
static void
gimp_toolbox_drop_buffer (GtkWidget    *widget,
                          gint          x,
                          gint          y,
                          GimpViewable *viewable,
                          gpointer      data)
{
  GimpContext *context = GIMP_CONTEXT (data);
  GimpImage   *image;

  if (context->gimp->busy)
    return;

  image = gimp_image_new_from_buffer (context->gimp, NULL,
                                      GIMP_BUFFER (viewable));
  gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0);
  g_object_unref (image);
}
예제 #15
0
static void
gimp_buffer_get_preview_size (GimpViewable *viewable,
                              gint          size,
                              gboolean      is_popup,
                              gboolean      dot_for_dot,
                              gint         *width,
                              gint         *height)
{
  GimpBuffer *buffer = GIMP_BUFFER (viewable);

  gimp_viewable_calc_preview_size (gimp_buffer_get_width (buffer),
                                   gimp_buffer_get_height (buffer),
                                   size,
                                   size,
                                   dot_for_dot, 1.0, 1.0,
                                   width,
                                   height,
                                   NULL);
}
예제 #16
0
파일: gimp-edit.c 프로젝트: ellelstone/gimp
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;
}
예제 #17
0
static gboolean
gimp_buffer_get_popup_size (GimpViewable *viewable,
                            gint          width,
                            gint          height,
                            gboolean      dot_for_dot,
                            gint         *popup_width,
                            gint         *popup_height)
{
  GimpBuffer *buffer;
  gint        buffer_width;
  gint        buffer_height;

  buffer        = GIMP_BUFFER (viewable);
  buffer_width  = gimp_buffer_get_width (buffer);
  buffer_height = gimp_buffer_get_height (buffer);

  if (buffer_width > width || buffer_height > height)
    {
      gboolean scaling_up;

      gimp_viewable_calc_preview_size (buffer_width,
                                       buffer_height,
                                       width  * 2,
                                       height * 2,
                                       dot_for_dot, 1.0, 1.0,
                                       popup_width,
                                       popup_height,
                                       &scaling_up);

      if (scaling_up)
        {
          *popup_width  = buffer_width;
          *popup_height = buffer_height;
        }

      return TRUE;
    }

  return FALSE;
}
예제 #18
0
static void
gimp_display_shell_drop_buffer (GtkWidget    *widget,
                                gint          drop_x,
                                gint          drop_y,
                                GimpViewable *viewable,
                                gpointer      data)
{
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image = gimp_display_get_image (shell->display);
  GimpDrawable     *drawable;
  GimpBuffer       *buffer;
  GimpPasteType     paste_type;
  gint              x, y, width, height;

  GIMP_LOG (DND, NULL);

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

  if (! image)
    {
      image = gimp_image_new_from_buffer (shell->display->gimp, NULL,
                                          GIMP_BUFFER (viewable));
      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0,
                           G_OBJECT (gtk_widget_get_screen (widget)),
                           gimp_widget_get_monitor (widget));
      g_object_unref (image);

      return;
    }

  paste_type = GIMP_PASTE_TYPE_FLOATING;

  drawable = gimp_image_get_active_drawable (image);

  if (drawable)
    {
      if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
        {
          gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
                                GIMP_MESSAGE_INFO,
                                _("Pasted as new layer because the "
                                  "target is a layer group."));

          paste_type = GIMP_PASTE_TYPE_NEW_LAYER;
        }
      else if (gimp_item_is_content_locked (GIMP_ITEM (drawable)))
        {
          gimp_message_literal (shell->display->gimp, G_OBJECT (shell->display),
                                GIMP_MESSAGE_ERROR,
                                _("Pasted as new layer because the "
                                  "target's pixels are locked."));

          paste_type = GIMP_PASTE_TYPE_NEW_LAYER;
        }
    }

  buffer = GIMP_BUFFER (viewable);

  gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height);

  /* FIXME: popup a menu for selecting "Paste Into" */

  gimp_edit_paste (image, drawable, GIMP_OBJECT (buffer),
                   paste_type, x, y, width, height);

  gimp_display_shell_dnd_flush (shell, image);
}
예제 #19
0
파일: gimp-edit.c 프로젝트: LebedevRI/gimp
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;
}
예제 #20
0
static GdkPixbuf *
gimp_buffer_get_new_pixbuf (GimpViewable *viewable,
                            GimpContext  *context,
                            gint          width,
                            gint          height)
{
  GimpBuffer *buffer = GIMP_BUFFER (viewable);
  GdkPixbuf  *pixbuf;
  gdouble     scale;

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

  scale = MIN ((gdouble) width  / (gdouble) gimp_buffer_get_width (buffer),
               (gdouble) height / (gdouble) gimp_buffer_get_height (buffer));

  if (buffer->color_profile)
    {
      GimpColorProfile *srgb_profile;
      GimpTempBuf      *temp_buf;
      GeglBuffer       *src_buf;
      GeglBuffer       *dest_buf;

      srgb_profile = gimp_color_profile_new_rgb_srgb ();

      temp_buf = gimp_temp_buf_new (width, height,
                                    gimp_buffer_get_format (buffer));

      gegl_buffer_get (buffer->buffer,
                       GEGL_RECTANGLE (0, 0, width, height),
                       scale,
                       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_gegl_convert_color_profile (src_buf,
                                       GEGL_RECTANGLE (0, 0, width, height),
                                       buffer->color_profile,
                                       dest_buf,
                                       GEGL_RECTANGLE (0, 0, 0, 0),
                                       srgb_profile,
                                       GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
                                       TRUE,
                                       NULL);

      g_object_unref (src_buf);
      g_object_unref (dest_buf);

      g_object_unref (srgb_profile);
    }
  else
    {
      gegl_buffer_get (buffer->buffer,
                       GEGL_RECTANGLE (0, 0, width, height),
                       scale,
                       gimp_pixbuf_get_format (pixbuf),
                       gdk_pixbuf_get_pixels (pixbuf),
                       gdk_pixbuf_get_rowstride (pixbuf),
                       GEGL_ABYSS_CLAMP);
    }

  return pixbuf;
}