diff options
Diffstat (limited to 'gdk-pixbuf/gnome-canvas-pixbuf.c')
-rw-r--r-- | gdk-pixbuf/gnome-canvas-pixbuf.c | 841 |
1 files changed, 0 insertions, 841 deletions
diff --git a/gdk-pixbuf/gnome-canvas-pixbuf.c b/gdk-pixbuf/gnome-canvas-pixbuf.c deleted file mode 100644 index a6372b9973..0000000000 --- a/gdk-pixbuf/gnome-canvas-pixbuf.c +++ /dev/null @@ -1,841 +0,0 @@ -/* GNOME libraries - GdkPixbuf item for the GNOME canvas - * - * Copyright (C) 1999 The Free Software Foundation - * - * Author: Federico Mena-Quintero <federico@gimp.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <math.h> -#include <libgnomeui/gnome-canvas.h> -#include <libgnomeui/gnome-canvas-util.h> -#include <libart_lgpl/art_rgb_affine.h> -#include <libart_lgpl/art_rgb_rgba_affine.h> -#include "gdk-pixbuf-private.h" -#include "gnome-canvas-pixbuf.h" - - - -/* Private part of the GnomeCanvasPixbuf structure */ -typedef struct { - /* Our gdk-pixbuf */ - GdkPixbuf *pixbuf; - - /* Width value */ - double width; - - /* Height value */ - double height; - - /* X translation */ - double x; - - /* Y translation */ - double y; - - /* Whether dimensions are set and whether they are in pixels or units */ - guint width_set : 1; - guint width_in_pixels : 1; - guint height_set : 1; - guint height_in_pixels : 1; - guint x_in_pixels : 1; - guint y_in_pixels : 1; - - /* Whether the pixbuf has changed */ - guint need_pixbuf_update : 1; - - /* Whether the transformation or size have changed */ - guint need_xform_update : 1; -} PixbufPrivate; - - - -/* Object argument IDs */ -enum { - ARG_0, - ARG_PIXBUF, - ARG_WIDTH, - ARG_WIDTH_SET, - ARG_WIDTH_IN_PIXELS, - ARG_HEIGHT, - ARG_HEIGHT_SET, - ARG_HEIGHT_IN_PIXELS, - ARG_X, - ARG_X_IN_PIXELS, - ARG_Y, - ARG_Y_IN_PIXELS -}; - -static void gnome_canvas_pixbuf_class_init (GnomeCanvasPixbufClass *class); -static void gnome_canvas_pixbuf_init (GnomeCanvasPixbuf *cpb); -static void gnome_canvas_pixbuf_destroy (GtkObject *object); -static void gnome_canvas_pixbuf_set_arg (GtkObject *object, GtkArg *arg, guint arg_id); -static void gnome_canvas_pixbuf_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); - -static void gnome_canvas_pixbuf_update (GnomeCanvasItem *item, double *affine, - ArtSVP *clip_path, int flags); -static void gnome_canvas_pixbuf_draw (GnomeCanvasItem *item, GdkDrawable *drawable, - int x, int y, int width, int height); -static void gnome_canvas_pixbuf_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf); -static double gnome_canvas_pixbuf_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, - GnomeCanvasItem **actual_item); -static void gnome_canvas_pixbuf_bounds (GnomeCanvasItem *item, - double *x1, double *y1, double *x2, double *y2); - -static GnomeCanvasItemClass *parent_class; - - - -/** - * gnome_canvas_pixbuf_get_type: - * @void: - * - * Registers the #GnomeCanvasPixbuf class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #GnomeCanvasPixbuf class. - **/ -GtkType -gnome_canvas_pixbuf_get_type (void) -{ - static GtkType canvas_pixbuf_type = 0; - - if (!canvas_pixbuf_type) { - static const GtkTypeInfo canvas_pixbuf_info = { - "GnomeCanvasPixbuf", - sizeof (GnomeCanvasPixbuf), - sizeof (GnomeCanvasPixbufClass), - (GtkClassInitFunc) gnome_canvas_pixbuf_class_init, - (GtkObjectInitFunc) gnome_canvas_pixbuf_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - canvas_pixbuf_type = gtk_type_unique (gnome_canvas_item_get_type (), - &canvas_pixbuf_info); - } - - return canvas_pixbuf_type; -} - -/* Class initialization function for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_class_init (GnomeCanvasPixbufClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - object_class = (GtkObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type ()); - - gtk_object_add_arg_type ("GnomeCanvasPixbuf::pixbuf", - GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_PIXBUF); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::width", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_WIDTH); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::width_set", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_WIDTH_SET); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::width_in_pixels", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_WIDTH_IN_PIXELS); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::height", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_HEIGHT); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::height_set", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HEIGHT_SET); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::height_in_pixels", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HEIGHT_IN_PIXELS); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::x", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_X); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::x_in_pixels", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_X_IN_PIXELS); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::y", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_Y); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::y_in_pixels", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_Y_IN_PIXELS); - - - object_class->destroy = gnome_canvas_pixbuf_destroy; - object_class->set_arg = gnome_canvas_pixbuf_set_arg; - object_class->get_arg = gnome_canvas_pixbuf_get_arg; - - item_class->update = gnome_canvas_pixbuf_update; - item_class->draw = gnome_canvas_pixbuf_draw; - item_class->render = gnome_canvas_pixbuf_render; - item_class->point = gnome_canvas_pixbuf_point; - item_class->bounds = gnome_canvas_pixbuf_bounds; -} - -/* Object initialization function for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_init (GnomeCanvasPixbuf *gcp) -{ - PixbufPrivate *priv; - - priv = g_new0 (PixbufPrivate, 1); - gcp->priv = priv; - - priv->width = 0.0; - priv->height = 0.0; - priv->x = 0.0; - priv->y = 0.0; -} - -/* Destroy handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_destroy (GtkObject *object) -{ - GnomeCanvasItem *item; - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (GNOME_IS_CANVAS_PIXBUF (object)); - - item = GNOME_CANVAS_ITEM (object); - gcp = (GNOME_CANVAS_PIXBUF (object)); - priv = gcp->priv; - - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - - if (priv->pixbuf) - gdk_pixbuf_unref (priv->pixbuf); - - g_free (priv); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* Set_arg handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - GdkPixbuf *pixbuf; - double val; - - item = GNOME_CANVAS_ITEM (object); - gcp = GNOME_CANVAS_PIXBUF (object); - priv = gcp->priv; - - switch (arg_id) { - case ARG_PIXBUF: - pixbuf = GTK_VALUE_POINTER (*arg); - if (pixbuf != priv->pixbuf) { - if (pixbuf) { - g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB); - g_return_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4); - g_return_if_fail (pixbuf->bits_per_sample == 8); - - gdk_pixbuf_ref (pixbuf); - } - - if (priv->pixbuf) - gdk_pixbuf_unref (priv->pixbuf); - - priv->pixbuf = pixbuf; - } - - priv->need_pixbuf_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_WIDTH: - val = GTK_VALUE_DOUBLE (*arg); - g_return_if_fail (val >= 0.0); - priv->width = val; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_WIDTH_SET: - priv->width_set = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_WIDTH_IN_PIXELS: - priv->width_in_pixels = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_HEIGHT: - val = GTK_VALUE_DOUBLE (*arg); - g_return_if_fail (val >= 0.0); - priv->height = val; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_HEIGHT_SET: - priv->height_set = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_HEIGHT_IN_PIXELS: - priv->height_in_pixels = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_X: - priv->x = GTK_VALUE_DOUBLE (*arg); - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_X_IN_PIXELS: - priv->x_in_pixels = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_Y: - priv->y = GTK_VALUE_DOUBLE (*arg); - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_Y_IN_PIXELS: - priv->y_in_pixels = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - default: - break; - } -} - -/* Get_arg handler for the pixbuf canvasi item */ -static void -gnome_canvas_pixbuf_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - - gcp = GNOME_CANVAS_PIXBUF (object); - priv = gcp->priv; - - switch (arg_id) { - case ARG_PIXBUF: - GTK_VALUE_POINTER (*arg) = priv->pixbuf; - break; - - case ARG_WIDTH: - GTK_VALUE_DOUBLE (*arg) = priv->width; - break; - - case ARG_WIDTH_SET: - GTK_VALUE_BOOL (*arg) = priv->width_set; - break; - - case ARG_WIDTH_IN_PIXELS: - GTK_VALUE_BOOL (*arg) = priv->width_in_pixels; - break; - - case ARG_HEIGHT: - GTK_VALUE_DOUBLE (*arg) = priv->height; - break; - - case ARG_HEIGHT_SET: - GTK_VALUE_BOOL (*arg) = priv->height_set; - break; - - case ARG_HEIGHT_IN_PIXELS: - GTK_VALUE_BOOL (*arg) = priv->height_in_pixels; - break; - - case ARG_X: - GTK_VALUE_DOUBLE (*arg) = priv->x; - break; - - case ARG_X_IN_PIXELS: - GTK_VALUE_BOOL (*arg) = priv->x_in_pixels; - break; - - case ARG_Y: - GTK_VALUE_DOUBLE (*arg) = priv->y; - break; - - case ARG_Y_IN_PIXELS: - GTK_VALUE_BOOL (*arg) = priv->y_in_pixels; - break; - - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - - - -/* Bounds and utilities */ - -/* Computes the amount by which the unit horizontal and vertical vectors will be - * scaled by an affine transformation. - */ -static void -compute_xform_scaling (double *affine, ArtPoint *i_c, ArtPoint *j_c) -{ - ArtPoint orig, orig_c; - ArtPoint i, j; - - /* Origin */ - - orig.x = 0.0; - orig.y = 0.0; - art_affine_point (&orig_c, &orig, affine); - - /* Horizontal and vertical vectors */ - - i.x = 1.0; - i.y = 0.0; - art_affine_point (i_c, &i, affine); - i_c->x -= orig_c.x; - i_c->y -= orig_c.y; - - j.x = 0.0; - j.y = 1.0; - art_affine_point (j_c, &j, affine); - j_c->x -= orig_c.x; - j_c->y -= orig_c.y; -} - -/* computes the addtional resolution dependent affine needed to - * fit the image within its viewport defined by x,y,width and height - * args - */ -static void -compute_viewport_affine (GnomeCanvasPixbuf *gcp, double *viewport_affine, double *i2c) -{ - PixbufPrivate *priv; - ArtPoint i_c, j_c; - double i_len, j_len; - double si_len, sj_len; - double ti_len, tj_len; - double scale[6], translate[6]; - double w, h; - - priv = gcp->priv; - - /* Compute scaling vectors and required width/height */ - - compute_xform_scaling (i2c, &i_c, &j_c); - - i_len = sqrt (i_c.x * i_c.x + i_c.y * i_c.y); - j_len = sqrt (j_c.x * j_c.x + j_c.y * j_c.y); - - if (priv->width_set) - w = priv->width; - else - w = priv->pixbuf->width; - - if (priv->height_set) - h = priv->height; - else - h = priv->pixbuf->height; - - /* Convert i_len and j_len into scaling factors */ - - if (priv->width_in_pixels) { - if (i_len > GNOME_CANVAS_EPSILON) - si_len = 1.0 / i_len; - else - si_len = 0.0; - } else - si_len = 1.0; - - si_len *= w / priv->pixbuf->width; - - if (priv->height_in_pixels) { - if (j_len > GNOME_CANVAS_EPSILON) - sj_len = 1.0 / j_len; - else - sj_len = 0.0; - } else - sj_len = 1.0; - - sj_len *= h / priv->pixbuf->height; - - /* Calculate translation offsets */ - - if (priv->x_in_pixels) { - if (i_len > GNOME_CANVAS_EPSILON) - ti_len = 1.0 / i_len; - else - ti_len = 0.0; - } else - ti_len = 1.0; - - ti_len *= priv->x; - - if (priv->y_in_pixels) { - if (j_len > GNOME_CANVAS_EPSILON) - tj_len = 1.0 / j_len; - else - tj_len = 0.0; - } else - tj_len = 1.0; - - tj_len *= priv->y; - - /* Compute the final affine */ - - art_affine_scale (scale, si_len, sj_len); - art_affine_translate (translate, ti_len, tj_len); - art_affine_multiply (viewport_affine, scale, translate); -} - -/* Computes the affine transformation with which the pixbuf needs to be - * transformed to render it on the canvas. This is not the same as the - * item_to_canvas transformation because we may need to scale the pixbuf - * by some other amount. - */ -static void -compute_render_affine (GnomeCanvasPixbuf *gcp, double *render_affine, double *i2c) -{ - double viewport_affine[6]; - - compute_viewport_affine (gcp, viewport_affine, i2c); - art_affine_multiply (render_affine, viewport_affine, i2c); -} - -/* Recomputes the bounding box of a pixbuf canvas item. The horizontal and - * vertical dimensions may be specified in units or pixels, separately, so we - * have to compute the components individually for each dimension. - */ -static void -recompute_bounding_box (GnomeCanvasPixbuf *gcp) -{ - GnomeCanvasItem *item; - PixbufPrivate *priv; - double i2c[6], render_affine[6]; - ArtDRect rect; - - item = GNOME_CANVAS_ITEM (gcp); - priv = gcp->priv; - - if (!priv->pixbuf) { - item->x1 = item->y1 = item->x2 = item->y2 = 0.0; - return; - } - - rect.x0 = 0.0; - rect.x1 = priv->pixbuf->width; - - rect.y0 = 0.0; - rect.y1 = priv->pixbuf->height; - - gnome_canvas_item_i2c_affine (item, i2c); - compute_render_affine (gcp, render_affine, i2c); - art_drect_affine_transform (&rect, &rect, render_affine); - - item->x1 = floor (rect.x0); - item->y1 = floor (rect.y0); - item->x2 = ceil (rect.x1); - item->y2 = ceil (rect.y1); -} - - - -/* Update sequence */ - -/* Update handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - - gcp = GNOME_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (parent_class->update) - (* parent_class->update) (item, affine, clip_path, flags); - - if (((flags & GNOME_CANVAS_UPDATE_VISIBILITY) - && !(GTK_OBJECT_FLAGS (item) & GNOME_CANVAS_ITEM_VISIBLE)) - || (flags & GNOME_CANVAS_UPDATE_AFFINE) - || priv->need_pixbuf_update - || priv->need_xform_update) - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - - /* If we need a pixbuf update, or if the item changed visibility to - * shown, recompute the bounding box. - */ - if (priv->need_pixbuf_update - || priv->need_xform_update - || ((flags & GNOME_CANVAS_UPDATE_VISIBILITY) - && (GTK_OBJECT_FLAGS (gcp) & GNOME_CANVAS_ITEM_VISIBLE)) - || (flags & GNOME_CANVAS_UPDATE_AFFINE)) { - recompute_bounding_box (gcp); - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - priv->need_pixbuf_update = FALSE; - priv->need_xform_update = FALSE; - } -} - - - -/* Rendering */ - -/* This is private to libart, but we need it. Sigh. */ -extern void art_rgb_affine_run (int *p_x0, int *p_x1, int y, int src_width, int src_height, - const double affine[6]); - -/* Fills the specified buffer with the transformed version of a pixbuf */ -static void -transform_pixbuf (guchar *dest, int x, int y, int width, int height, int rowstride, - GdkPixbuf *pixbuf, double *affine) -{ - int xx, yy; - double inv[6]; - guchar *src, *d; - ArtPoint src_p, dest_p; - int run_x1, run_x2; - int src_x, src_y; - int i; - - art_affine_invert (inv, affine); - - for (yy = 0; yy < height; yy++) { - dest_p.y = y + yy + 0.5; - - run_x1 = x; - run_x2 = x + width; - art_rgb_affine_run (&run_x1, &run_x2, yy + y, - pixbuf->width, pixbuf->height, - inv); - - d = dest + yy * rowstride + (run_x1 - x) * 4; - - for (xx = run_x1; xx < run_x2; xx++) { - dest_p.x = xx + 0.5; - art_affine_point (&src_p, &dest_p, inv); - src_x = floor (src_p.x); - src_y = floor (src_p.y); - - src = pixbuf->pixels + src_y * pixbuf->rowstride + src_x * pixbuf->n_channels; - - for (i = 0; i < pixbuf->n_channels; i++) - *d++ = *src++; - - if (!pixbuf->has_alpha) - *d++ = 255; /* opaque */ - } - } -} - -/* Draw handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_draw (GnomeCanvasItem *item, GdkDrawable *drawable, - int x, int y, int width, int height) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - double i2c[6], render_affine[6]; - guchar *buf; - GdkPixbuf *pixbuf; - ArtIRect p_rect, a_rect, d_rect; - int w, h; - - gcp = GNOME_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (!priv->pixbuf) - return; - - gnome_canvas_item_i2c_affine (item, i2c); - compute_render_affine (gcp, render_affine, i2c); - - /* Compute the area we need to repaint */ - - p_rect.x0 = item->x1; - p_rect.y0 = item->y1; - p_rect.x1 = item->x2; - p_rect.y1 = item->y2; - - a_rect.x0 = x; - a_rect.y0 = y; - a_rect.x1 = x + width; - a_rect.y1 = y + height; - - art_irect_intersect (&d_rect, &p_rect, &a_rect); - if (art_irect_empty (&d_rect)) - return; - - /* Create a temporary buffer and transform the pixbuf there */ - - w = d_rect.x1 - d_rect.x0; - h = d_rect.y1 - d_rect.y0; - - buf = g_new0 (guchar, w * h * 4); - transform_pixbuf (buf, - d_rect.x0, d_rect.y0, - w, h, - w * 4, - priv->pixbuf, render_affine); - - pixbuf = gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB, TRUE, 8, w, h, w * 4, NULL, NULL); - - gdk_pixbuf_render_to_drawable_alpha (pixbuf, drawable, - 0, 0, - d_rect.x0 - x, d_rect.y0 - y, - w, h, - GDK_PIXBUF_ALPHA_BILEVEL, - 128, - GDK_RGB_DITHER_MAX, - d_rect.x0, d_rect.y0); - - gdk_pixbuf_unref (pixbuf); - g_free (buf); -} - -/* Render handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - double i2c[6], render_affine[6]; - - gcp = GNOME_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (!priv->pixbuf) - return; - - gnome_canvas_item_i2c_affine (item, i2c); - compute_render_affine (gcp, render_affine, i2c); - gnome_canvas_buf_ensure_buf (buf); - - if (priv->pixbuf->has_alpha) - art_rgb_rgba_affine (buf->buf, - buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1, - buf->buf_rowstride, - priv->pixbuf->pixels, - priv->pixbuf->width, priv->pixbuf->height, - priv->pixbuf->rowstride, - render_affine, - ART_FILTER_NEAREST, - NULL); - else - art_rgb_affine (buf->buf, - buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1, - buf->buf_rowstride, - priv->pixbuf->pixels, - priv->pixbuf->width, priv->pixbuf->height, - priv->pixbuf->rowstride, - render_affine, - ART_FILTER_NEAREST, - NULL); - - buf->is_bg = FALSE; -} - - - -/* Point handler for the pixbuf canvas item */ -static double -gnome_canvas_pixbuf_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, - GnomeCanvasItem **actual_item) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - double i2c[6], render_affine[6], inv[6]; - ArtPoint c, p; - int px, py; - double no_hit; - guchar *src; - - gcp = GNOME_CANVAS_PIXBUF (item); - priv = gcp->priv; - - *actual_item = item; - - no_hit = item->canvas->pixels_per_unit * 2 + 10; - - if (!priv->pixbuf) - return no_hit; - - gnome_canvas_item_i2c_affine (item, i2c); - compute_render_affine (gcp, render_affine, i2c); - art_affine_invert (inv, render_affine); - - c.x = cx; - c.y = cy; - art_affine_point (&p, &c, inv); - px = p.x; - py = p.y; - - if (px < 0 || px >= priv->pixbuf->width || py < 0 || py >= priv->pixbuf->height) - return no_hit; - - if (!priv->pixbuf->has_alpha) - return 0.0; - - src = priv->pixbuf->pixels + py * priv->pixbuf->rowstride + px * priv->pixbuf->n_channels; - - if (src[3] < 128) - return no_hit; - else - return 0.0; -} - - - -/* Bounds handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - double i2c[6], viewport_affine[6]; - ArtDRect rect; - - gcp = GNOME_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (!priv->pixbuf) { - *x1 = *y1 = *x2 = *y2 = 0.0; - return; - } - - rect.x0 = 0.0; - rect.x1 = priv->pixbuf->width; - - rect.y0 = 0.0; - rect.y1 = priv->pixbuf->height; - - gnome_canvas_item_i2c_affine (item, i2c); - compute_viewport_affine (gcp, viewport_affine, i2c); - art_drect_affine_transform (&rect, &rect, viewport_affine); - - *x1 = rect.x0; - *y1 = rect.y0; - *x2 = rect.x1; - *y2 = rect.y1; -} |