Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  gimpimageproxy.c   Sprache: C

 

/* GIMP - The GNU Image Manipulation Program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * gimpimageproxy.c
 * Copyright (C) 2019 Ell
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */


#include "config.h"

#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>

#include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h"

#include "core-types.h"

#include "gegl/gimp-babl.h"
#include "gegl/gimp-gegl-loops.h"

#include "gimpimage.h"
#include "gimpimage-color-profile.h"
#include "gimpimage-preview.h"
#include "gimpimageproxy.h"
#include "gimppickable.h"
#include "gimpprojectable.h"
#include "gimptempbuf.h"


enum
{
  PROP_0,
  PROP_IMAGE,
  PROP_SHOW_ALL,
  PROP_BUFFER
};


struct _GimpImageProxyPrivate
{
  GimpImage     *image;
  gboolean       show_all;

  GeglRectangle  bounding_box;
  gboolean       frozen;
};


/*  local function prototypes  */

static void               gimp_image_proxy_pickable_iface_init      (GimpPickableInterface      *iface);
static void               gimp_image_proxy_color_managed_iface_init (GimpColorManagedInterface  *iface);

static void               gimp_image_proxy_finalize                 (GObject                    *object);
static void               gimp_image_proxy_set_property             (GObject                    *object,
                                                                     guint                       property_id,
                                                                     const GValue               *value,
                                                                     GParamSpec                 *pspec);
static void               gimp_image_proxy_get_property             (GObject                    *object,
                                                                     guint                       property_id,
                                                                     GValue                     *value,
                                                                     GParamSpec                 *pspec);

static gboolean           gimp_image_proxy_get_size                 (GimpViewable               *viewable,
                                                                     gint                       *width,
                                                                     gint                       *height);
static void               gimp_image_proxy_get_preview_size         (GimpViewable               *viewable,
                                                                     gint                        size,
                                                                     gboolean                    is_popup,
                                                                     gboolean                    dot_for_dot,
                                                                     gint                       *width,
                                                                     gint                       *height);
static gboolean           gimp_image_proxy_get_popup_size           (GimpViewable               *viewable,
                                                                     gint                        width,
                                                                     gint                        height,
                                                                     gboolean                    dot_for_dot,
                                                                     gint                       *popup_width,
                                                                     gint                       *popup_height);
static GimpTempBuf      * gimp_image_proxy_get_new_preview          (GimpViewable               *viewable,
                                                                     GimpContext                *context,
                                                                     gint                        width,
                                                                     gint                        height,
                                                                     GeglColor                  *fg_color);
static GdkPixbuf        * gimp_image_proxy_get_new_pixbuf           (GimpViewable               *viewable,
                                                                     GimpContext                *context,
                                                                     gint                        width,
                                                                     gint                        height,
                                                                     GeglColor                  *fg_color);
static gchar            * gimp_image_proxy_get_description          (GimpViewable               *viewable,
                                                                     gchar                     **tooltip);

static void               gimp_image_proxy_flush                    (GimpPickable               *pickable);
static const Babl       * gimp_image_proxy_get_format               (GimpPickable               *pickable);
static const Babl       * gimp_image_proxy_get_format_with_alpha    (GimpPickable               *pickable);
static GeglBuffer       * gimp_image_proxy_get_buffer               (GimpPickable               *pickable);
static gboolean           gimp_image_proxy_get_pixel_at             (GimpPickable               *pickable,
                                                                     gint                        x,
                                                                     gint                        y,
                                                                     const Babl                 *format,
                                                                     gpointer                    pixel);
static gdouble            gimp_image_proxy_get_opacity_at           (GimpPickable               *pickable,
                                                                     gint                        x,
                                                                     gint                        y);
static void               gimp_image_proxy_get_pixel_average        (GimpPickable               *pickable,
                                                                     const GeglRectangle        *rect,
                                                                     const Babl                 *format,
                                                                     gpointer                    pixel);

static const guint8     * gimp_image_proxy_get_icc_profile          (GimpColorManaged           *managed,
                                                                     gsize                      *len);
static GimpColorProfile * gimp_image_proxy_get_color_profile        (GimpColorManaged           *managed);
static void               gimp_image_proxy_profile_changed          (GimpColorManaged           *managed);

static void               gimp_image_proxy_image_frozen_notify      (GimpImage                  *image,
                                                                     const GParamSpec           *pspec,
                                                                     GimpImageProxy             *image_proxy);
static void               gimp_image_proxy_image_invalidate_preview (GimpImage                  *image,
                                                                     GimpImageProxy             *image_proxy);
static void               gimp_image_proxy_image_size_changed       (GimpImage                  *image,
                                                                     GimpImageProxy             *image_proxy);
static void               gimp_image_proxy_image_bounds_changed     (GimpImage                  *image,
                                                                     gint                        old_x,
                                                                     gint                        old_y,
                                                                     GimpImageProxy             *image_proxy);
static void               gimp_image_proxy_image_profile_changed    (GimpImage                  *image,
                                                                     GimpImageProxy             *image_proxy);

static void               gimp_image_proxy_set_image                (GimpImageProxy             *image_proxy,
                                                                     GimpImage                  *image);
static GimpPickable     * gimp_image_proxy_get_pickable             (GimpImageProxy             *image_proxy);
static void               gimp_image_proxy_update_bounding_box      (GimpImageProxy             *image_proxy);
static void               gimp_image_proxy_update_frozen            (GimpImageProxy             *image_proxy);


G_DEFINE_TYPE_WITH_CODE (GimpImageProxy, gimp_image_proxy, GIMP_TYPE_VIEWABLE,
                         G_ADD_PRIVATE (GimpImageProxy)
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_PICKABLE,
                                                gimp_image_proxy_pickable_iface_init)
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_COLOR_MANAGED,
                                                gimp_image_proxy_color_managed_iface_init))

#define parent_class gimp_image_proxy_parent_class


/*  private functions  */


static void
gimp_image_proxy_class_init (GimpImageProxyClass *klass)
{
  GObjectClass      *object_class   = G_OBJECT_CLASS (klass);
  GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);

  object_class->finalize            = gimp_image_proxy_finalize;
  object_class->set_property        = gimp_image_proxy_set_property;
  object_class->get_property        = gimp_image_proxy_get_property;

  viewable_class->default_icon_name = "gimp-image";
  viewable_class->get_size          = gimp_image_proxy_get_size;
  viewable_class->get_preview_size  = gimp_image_proxy_get_preview_size;
  viewable_class->get_popup_size    = gimp_image_proxy_get_popup_size;
  viewable_class->get_new_preview   = gimp_image_proxy_get_new_preview;
  viewable_class->get_new_pixbuf    = gimp_image_proxy_get_new_pixbuf;
  viewable_class->get_description   = gimp_image_proxy_get_description;

  g_object_class_install_property (object_class, PROP_IMAGE,
                                   g_param_spec_object ("image",
                                                        NULL, NULL,
                                                        GIMP_TYPE_IMAGE,
                                                        GIMP_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY));

  g_object_class_install_property (object_class, PROP_SHOW_ALL,
                                   g_param_spec_boolean ("show-all",
                                                         NULL, NULL,
                                                         FALSE,
                                                         GIMP_PARAM_READWRITE |
                                                         G_PARAM_CONSTRUCT));

  g_object_class_override_property (object_class, PROP_BUFFER, "buffer");
}

static void
gimp_image_proxy_pickable_iface_init (GimpPickableInterface *iface)
{
  iface->flush                 = gimp_image_proxy_flush;
  iface->get_image             = (gpointer) gimp_image_proxy_get_image;
  iface->get_format            = gimp_image_proxy_get_format;
  iface->get_format_with_alpha = gimp_image_proxy_get_format_with_alpha;
  iface->get_buffer            = gimp_image_proxy_get_buffer;
  iface->get_pixel_at          = gimp_image_proxy_get_pixel_at;
  iface->get_opacity_at        = gimp_image_proxy_get_opacity_at;
  iface->get_pixel_average     = gimp_image_proxy_get_pixel_average;
}

static void
gimp_image_proxy_color_managed_iface_init (GimpColorManagedInterface *iface)
{
  iface->get_icc_profile   = gimp_image_proxy_get_icc_profile;
  iface->get_color_profile = gimp_image_proxy_get_color_profile;
  iface->profile_changed   = gimp_image_proxy_profile_changed;
}

static void
gimp_image_proxy_init (GimpImageProxy *image_proxy)
{
  image_proxy->priv = gimp_image_proxy_get_instance_private (image_proxy);
}

static void
gimp_image_proxy_finalize (GObject *object)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (object);

  gimp_image_proxy_set_image (image_proxy, NULL);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gimp_image_proxy_set_property (GObject      *object,
                               guint         property_id,
                               const GValue *value,
                               GParamSpec   *pspec)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (object);

  switch (property_id)
    {
    case PROP_IMAGE:
      gimp_image_proxy_set_image (image_proxy,
                                  g_value_get_object (value));
      break;

    case PROP_SHOW_ALL:
      gimp_image_proxy_set_show_all (image_proxy,
                                     g_value_get_boolean (value));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static void
gimp_image_proxy_get_property (GObject    *object,
                               guint       property_id,
                               GValue     *value,
                               GParamSpec *pspec)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (object);

  switch (property_id)
    {
    case PROP_IMAGE:
      g_value_set_object (value,
                          gimp_image_proxy_get_image (image_proxy));
      break;

    case PROP_SHOW_ALL:
      g_value_set_boolean (value,
                           gimp_image_proxy_get_show_all (image_proxy));
      break;

    case PROP_BUFFER:
      g_value_set_object (value,
                          gimp_pickable_get_buffer (
                            GIMP_PICKABLE (image_proxy)));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static gboolean
gimp_image_proxy_get_size (GimpViewable *viewable,
                           gint         *width,
                           gint         *height)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (viewable);

  *width  = image_proxy->priv->bounding_box.width;
  *height = image_proxy->priv->bounding_box.height;

  return TRUE;
}

static void
gimp_image_proxy_get_preview_size (GimpViewable *viewable,
                                   gint          size,
                                   gboolean      is_popup,
                                   gboolean      dot_for_dot,
                                   gint         *width,
                                   gint         *height)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (viewable);
  GimpImage      *image       = image_proxy->priv->image;
  gdouble         xres;
  gdouble         yres;
  gint            viewable_width;
  gint            viewable_height;

  gimp_image_get_resolution (image, &xres, &yres);

  gimp_viewable_get_size (viewable, &viewable_width, &viewable_height);

  gimp_viewable_calc_preview_size (viewable_width,
                                   viewable_height,
                                   size,
                                   size,
                                   dot_for_dot,
                                   xres,
                                   yres,
                                   width,
                                   height,
                                   NULL);
}

static gboolean
gimp_image_proxy_get_popup_size (GimpViewable *viewable,
                                 gint          width,
                                 gint          height,
                                 gboolean      dot_for_dot,
                                 gint         *popup_width,
                                 gint         *popup_height)
{
  gint viewable_width;
  gint viewable_height;

  gimp_viewable_get_size (viewable, &viewable_width, &viewable_height);

  if (viewable_width > width || viewable_height > height)
    {
      gboolean scaling_up;

      gimp_viewable_calc_preview_size (viewable_width,
                                       viewable_height,
                                       width  * 2,
                                       height * 2,
                                       dot_for_dot, 1.0, 1.0,
                                       popup_width,
                                       popup_height,
                                       &scaling_up);

      if (scaling_up)
        {
          *popup_width  = viewable_width;
          *popup_height = viewable_height;
        }

      return TRUE;
    }

  return FALSE;
}

static GimpTempBuf *
gimp_image_proxy_get_new_preview (GimpViewable *viewable,
                                  GimpContext  *context,
                                  gint          width,
                                  gint          height,
                                  GeglColor    *fg_color G_GNUC_UNUSED)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (viewable);
  GimpImage      *image       = image_proxy->priv->image;
  GimpPickable   *pickable;
  const Babl     *format;
  GeglRectangle   bounding_box;
  GimpTempBuf    *buf;
  gdouble         scale_x;
  gdouble         scale_y;
  gdouble         scale;

  pickable     = gimp_image_proxy_get_pickable     (image_proxy);
  bounding_box = gimp_image_proxy_get_bounding_box (image_proxy);

  scale_x = (gdouble) width  / (gdouble) bounding_box.width;
  scale_y = (gdouble) height / (gdouble) bounding_box.height;

  scale   = MIN (scale_x, scale_y);

  format = gimp_image_get_preview_format (image);

  buf = gimp_temp_buf_new (width, height, format);

  gegl_buffer_get (gimp_pickable_get_buffer (pickable),
                   GEGL_RECTANGLE (bounding_box.x * scale,
                                   bounding_box.y * scale,
                                   width,
                                   height),
                   scale,
                   gimp_temp_buf_get_format (buf),
                   gimp_temp_buf_get_data (buf),
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);

  return buf;
}

static GdkPixbuf *
gimp_image_proxy_get_new_pixbuf (GimpViewable *viewable,
                                 GimpContext  *context,
                                 gint          width,
                                 gint          height,
                                 GeglColor    *fg_color G_GNUC_UNUSED)
{
  GimpImageProxy     *image_proxy = GIMP_IMAGE_PROXY (viewable);
  GimpImage          *image       = image_proxy->priv->image;
  GimpPickable       *pickable;
  GeglRectangle       bounding_box;
  GdkPixbuf          *pixbuf;
  gdouble             scale_x;
  gdouble             scale_y;
  gdouble             scale;
  GimpColorTransform *transform;

  pickable     = gimp_image_proxy_get_pickable     (image_proxy);
  bounding_box = gimp_image_proxy_get_bounding_box (image_proxy);

  scale_x = (gdouble) width  / (gdouble) bounding_box.width;
  scale_y = (gdouble) height / (gdouble) bounding_box.height;

  scale   = MIN (scale_x, scale_y);

  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 (pickable));

      gegl_buffer_get (gimp_pickable_get_buffer (pickable),
                       GEGL_RECTANGLE (bounding_box.x * scale,
                                       bounding_box.y * scale,
                                       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_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 (pickable),
                       GEGL_RECTANGLE (bounding_box.x * scale,
                                       bounding_box.y * scale,
                                       width,
                                       height),
                       scale,
                       gimp_pixbuf_get_format (pixbuf),
                       gdk_pixbuf_get_pixels (pixbuf),
                       gdk_pixbuf_get_rowstride (pixbuf),
                       GEGL_ABYSS_CLAMP);
    }

  return pixbuf;
}

static gchar *
gimp_image_proxy_get_description (GimpViewable  *viewable,
                                  gchar        **tooltip)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (viewable);
  GimpImage      *image       = image_proxy->priv->image;

  if (tooltip)
    *tooltip = g_strdup (gimp_image_get_display_path (image));

  return g_strdup_printf ("%s-%d",
                          gimp_image_get_display_name (image),
                          gimp_image_get_id (image));
}

static void
gimp_image_proxy_flush (GimpPickable *pickable)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (pickable);
  GimpPickable   *proxy_pickable;

  proxy_pickable = gimp_image_proxy_get_pickable (image_proxy);

  gimp_pickable_flush (proxy_pickable);
}

static const Babl *
gimp_image_proxy_get_format (GimpPickable *pickable)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (pickable);
  GimpPickable   *proxy_pickable;

  proxy_pickable = gimp_image_proxy_get_pickable (image_proxy);

  return gimp_pickable_get_format (proxy_pickable);
}

static const Babl *
gimp_image_proxy_get_format_with_alpha (GimpPickable *pickable)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (pickable);
  GimpPickable   *proxy_pickable;

  proxy_pickable = gimp_image_proxy_get_pickable (image_proxy);

  return gimp_pickable_get_format_with_alpha (proxy_pickable);
}

static GeglBuffer *
gimp_image_proxy_get_buffer (GimpPickable *pickable)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (pickable);
  GimpPickable   *proxy_pickable;

  proxy_pickable = gimp_image_proxy_get_pickable (image_proxy);

  return gimp_pickable_get_buffer (proxy_pickable);
}

static gboolean
gimp_image_proxy_get_pixel_at (GimpPickable *pickable,
                               gint          x,
                               gint          y,
                               const Babl   *format,
                               gpointer      pixel)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (pickable);
  GimpPickable   *proxy_pickable;

  proxy_pickable = gimp_image_proxy_get_pickable (image_proxy);

  return gimp_pickable_get_pixel_at (proxy_pickable, x, y, format, pixel);
}

static gdouble
gimp_image_proxy_get_opacity_at (GimpPickable *pickable,
                                 gint          x,
                                 gint          y)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (pickable);
  GimpPickable   *proxy_pickable;

  proxy_pickable = gimp_image_proxy_get_pickable (image_proxy);

  return gimp_pickable_get_opacity_at (proxy_pickable, x, y);
}

static void
gimp_image_proxy_get_pixel_average (GimpPickable        *pickable,
                                    const GeglRectangle *rect,
                                    const Babl          *format,
                                    gpointer             pixel)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (pickable);
  GimpPickable   *proxy_pickable;

  proxy_pickable = gimp_image_proxy_get_pickable (image_proxy);

  gimp_pickable_get_pixel_average (proxy_pickable, rect, format, pixel);
}

static const guint8 *
gimp_image_proxy_get_icc_profile (GimpColorManaged *managed,
                                  gsize            *len)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (managed);

  return gimp_color_managed_get_icc_profile (
    GIMP_COLOR_MANAGED (image_proxy->priv->image),
    len);
}

static GimpColorProfile *
gimp_image_proxy_get_color_profile (GimpColorManaged *managed)
{
  GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (managed);

  return gimp_color_managed_get_color_profile (
    GIMP_COLOR_MANAGED (image_proxy->priv->image));
}

static void
gimp_image_proxy_profile_changed (GimpColorManaged *managed)
{
  gimp_viewable_invalidate_preview (GIMP_VIEWABLE (managed));
}

static void
gimp_image_proxy_image_frozen_notify (GimpImage        *image,
                                      const GParamSpec *pspec,
                                      GimpImageProxy   *image_proxy)
{
  gimp_image_proxy_update_frozen (image_proxy);
}

static void
gimp_image_proxy_image_invalidate_preview (GimpImage      *image,
                                           GimpImageProxy *image_proxy)
{
  gimp_viewable_invalidate_preview (GIMP_VIEWABLE (image_proxy));
}

static void
gimp_image_proxy_image_size_changed (GimpImage      *image,
                                     GimpImageProxy *image_proxy)
{
  gimp_image_proxy_update_bounding_box (image_proxy);
}

static void
gimp_image_proxy_image_bounds_changed (GimpImage      *image,
                                       gint            old_x,
                                       gint            old_y,
                                       GimpImageProxy *image_proxy)
{
  gimp_image_proxy_update_bounding_box (image_proxy);
}

static void
gimp_image_proxy_image_profile_changed (GimpImage      *image,
                                        GimpImageProxy *image_proxy)
{
  gimp_color_managed_profile_changed (GIMP_COLOR_MANAGED (image_proxy));
}

static void
gimp_image_proxy_set_image (GimpImageProxy *image_proxy,
                            GimpImage      *image)
{
  if (image_proxy->priv->image)
    {
      g_signal_handlers_disconnect_by_func (
        image_proxy->priv->image,
        gimp_image_proxy_image_frozen_notify,
        image_proxy);
      g_signal_handlers_disconnect_by_func (
        image_proxy->priv->image,
        gimp_image_proxy_image_invalidate_preview,
        image_proxy);
      g_signal_handlers_disconnect_by_func (
        image_proxy->priv->image,
        gimp_image_proxy_image_size_changed,
        image_proxy);
      g_signal_handlers_disconnect_by_func (
        image_proxy->priv->image,
        gimp_image_proxy_image_bounds_changed,
        image_proxy);
      g_signal_handlers_disconnect_by_func (
        image_proxy->priv->image,
        gimp_image_proxy_image_profile_changed,
        image_proxy);

      g_object_unref (image_proxy->priv->image);
    }

  image_proxy->priv->image = image;

  if (image_proxy->priv->image)
    {
      g_object_ref (image_proxy->priv->image);

      g_signal_connect (
        image_proxy->priv->image, "notify::frozen",
        G_CALLBACK (gimp_image_proxy_image_frozen_notify),
        image_proxy);
      g_signal_connect (
        image_proxy->priv->image, "invalidate-preview",
        G_CALLBACK (gimp_image_proxy_image_invalidate_preview),
        image_proxy);
      g_signal_connect (
        image_proxy->priv->image, "size-changed",
        G_CALLBACK (gimp_image_proxy_image_size_changed),
        image_proxy);
      g_signal_connect (
        image_proxy->priv->image, "bounds-changed",
        G_CALLBACK (gimp_image_proxy_image_bounds_changed),
        image_proxy);
      g_signal_connect (
        image_proxy->priv->image, "profile-changed",
        G_CALLBACK (gimp_image_proxy_image_profile_changed),
        image_proxy);

      gimp_image_proxy_update_bounding_box (image_proxy);
      gimp_image_proxy_update_frozen (image_proxy);

      gimp_viewable_invalidate_preview (GIMP_VIEWABLE (image_proxy));
    }
}

static GimpPickable *
gimp_image_proxy_get_pickable (GimpImageProxy *image_proxy)
{
  GimpImage *image = image_proxy->priv->image;

  if (! image_proxy->priv->show_all)
    return GIMP_PICKABLE (image);
  else
    return GIMP_PICKABLE (gimp_image_get_projection (image));
}

static void
gimp_image_proxy_update_bounding_box (GimpImageProxy *image_proxy)
{
  GimpImage     *image = image_proxy->priv->image;
  GeglRectangle  bounding_box;

  if (gimp_viewable_preview_is_frozen (GIMP_VIEWABLE (image_proxy)))
    return;

  if (! image_proxy->priv->show_all)
    {
      bounding_box.x      = 0;
      bounding_box.y      = 0;
      bounding_box.width  = gimp_image_get_width  (image);
      bounding_box.height = gimp_image_get_height (image);
    }
  else
    {
      bounding_box = gimp_projectable_get_bounding_box (
        GIMP_PROJECTABLE (image));
    }

  if (! gegl_rectangle_equal (&bounding_box,
                              &image_proxy->priv->bounding_box))
    {
      image_proxy->priv->bounding_box = bounding_box;

      gimp_viewable_size_changed (GIMP_VIEWABLE (image_proxy));
    }
}

static void
gimp_image_proxy_update_frozen (GimpImageProxy *image_proxy)
{
  gboolean frozen;

  frozen = gimp_viewable_preview_is_frozen (
    GIMP_VIEWABLE (image_proxy->priv->image));

  if (frozen != image_proxy->priv->frozen)
    {
      image_proxy->priv->frozen = frozen;

      if (frozen)
        {
          gimp_viewable_preview_freeze (GIMP_VIEWABLE (image_proxy));
        }
      else
        {
          gimp_viewable_preview_thaw (GIMP_VIEWABLE (image_proxy));

          gimp_image_proxy_update_bounding_box (image_proxy);
        }
    }
}


/*  public functions  */


GimpImageProxy *
gimp_image_proxy_new (GimpImage *image)
{
  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  return g_object_new (GIMP_TYPE_IMAGE_PROXY,
                       "image", image,
                       NULL);
}

GimpImage *
gimp_image_proxy_get_image (GimpImageProxy *image_proxy)
{
  g_return_val_if_fail (GIMP_IS_IMAGE_PROXY (image_proxy), NULL);

  return image_proxy->priv->image;
}

void
gimp_image_proxy_set_show_all (GimpImageProxy *image_proxy,
                               gboolean        show_all)
{
  g_return_if_fail (GIMP_IS_IMAGE_PROXY (image_proxy));

  if (show_all != image_proxy->priv->show_all)
    {
      image_proxy->priv->show_all = show_all;

      gimp_image_proxy_update_bounding_box (image_proxy);
    }
}

gboolean
gimp_image_proxy_get_show_all (GimpImageProxy *image_proxy)
{
  g_return_val_if_fail (GIMP_IS_IMAGE_PROXY (image_proxy), FALSE);

  return image_proxy->priv->show_all;
}

GeglRectangle
gimp_image_proxy_get_bounding_box (GimpImageProxy *image_proxy)
{
  g_return_val_if_fail (GIMP_IS_IMAGE_PROXY (image_proxy),
                        *GEGL_RECTANGLE (0, 0, 0, 0));

  return image_proxy->priv->bounding_box;
}

Messung
CHZG
801009893

¤ Dauer der Verarbeitung: 0.5 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104856
#Domains=417283