/* 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 .
*/
#include "config.h"
#include
#include
#include
#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);
static GdkPixbuf * gimp_image_proxy_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height);
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 void gimp_image_proxy_pixel_to_srgb (GimpPickable *pickable,
const Babl *format,
gpointer pixel,
GimpRGB *color);
static void gimp_image_proxy_srgb_to_pixel (GimpPickable *pickable,
const GimpRGB *color,
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;
iface->pixel_to_srgb = gimp_image_proxy_pixel_to_srgb;
iface->srgb_to_pixel = gimp_image_proxy_srgb_to_pixel;
}
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)
{
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)
{
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 void
gimp_image_proxy_pixel_to_srgb (GimpPickable *pickable,
const Babl *format,
gpointer pixel,
GimpRGB *color)
{
GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (pickable);
GimpPickable *proxy_pickable;
proxy_pickable = gimp_image_proxy_get_pickable (image_proxy);
gimp_pickable_pixel_to_srgb (proxy_pickable, format, pixel, color);
}
static void
gimp_image_proxy_srgb_to_pixel (GimpPickable *pickable,
const GimpRGB *color,
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_srgb_to_pixel (proxy_pickable, color, 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;
}