diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2010-08-03 02:05:53 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2010-08-03 02:05:53 +0000 |
| commit | 4b9f09e52f05a19f93546c075c7a3fb7be322ed7 (patch) | |
| tree | f286d8509d4d47e58f37cb0f34ce62009085fe4b /src | |
| parent | Second half of image filter, probably not 100% correct (diff) | |
| download | inkscape-4b9f09e52f05a19f93546c075c7a3fb7be322ed7.tar.gz inkscape-4b9f09e52f05a19f93546c075c7a3fb7be322ed7.zip | |
Handle preserveAspectRatio for images
(bzr r9508.1.41)
Diffstat (limited to 'src')
| -rw-r--r-- | src/display/cairo-utils.cpp | 17 | ||||
| -rw-r--r-- | src/display/cairo-utils.h | 3 | ||||
| -rw-r--r-- | src/display/nr-arena-image.cpp | 179 | ||||
| -rw-r--r-- | src/display/nr-arena-image.h | 18 | ||||
| -rw-r--r-- | src/sp-image.cpp | 189 | ||||
| -rw-r--r-- | src/sp-image.h | 8 |
6 files changed, 209 insertions, 205 deletions
diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index a05d28170..25a1e7988 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -288,8 +288,17 @@ ink_cairo_set_source_color(cairo_t *ct, SPColor const &c, double opacity) cairo_set_source_rgba(ct, c.v.c[0], c.v.c[1], c.v.c[2], opacity); } -static void -ink_cairo_convert_matrix(cairo_matrix_t &cm, Geom::Matrix const &m) +void ink_matrix_to_2geom(Geom::Matrix &m, cairo_matrix_t const &cm) +{ + m[0] = cm.xx; + m[2] = cm.xy; + m[4] = cm.x0; + m[1] = cm.yx; + m[3] = cm.yy; + m[5] = cm.y0; +} + +void ink_matrix_to_cairo(cairo_matrix_t &cm, Geom::Matrix const &m) { cm.xx = m[0]; cm.xy = m[2]; @@ -303,7 +312,7 @@ void ink_cairo_transform(cairo_t *ct, Geom::Matrix const &m) { cairo_matrix_t cm; - ink_cairo_convert_matrix(cm, m); + ink_matrix_to_cairo(cm, m); cairo_transform(ct, &cm); } @@ -311,7 +320,7 @@ void ink_cairo_pattern_set_matrix(cairo_pattern_t *cp, Geom::Matrix const &m) { cairo_matrix_t cm; - ink_cairo_convert_matrix(cm, m); + ink_matrix_to_cairo(cm, m); cairo_pattern_set_matrix(cp, &cm); } diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index 12fcd8b3d..5ac546067 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -84,6 +84,9 @@ void ink_cairo_transform(cairo_t *ct, Geom::Matrix const &m); void ink_cairo_pattern_set_matrix(cairo_pattern_t *cp, Geom::Matrix const &m); void ink_cairo_set_source_argb32_pixbuf(cairo_t *ct, GdkPixbuf *pb, double x, double y); +void ink_matrix_to_2geom(Geom::Matrix &, cairo_matrix_t const &); +void ink_matrix_to_cairo(cairo_matrix_t &, Geom::Matrix const &); + cairo_surface_t *ink_cairo_surface_copy(cairo_surface_t *s); cairo_surface_t *ink_cairo_surface_create_identical(cairo_surface_t *s); cairo_surface_t *ink_cairo_surface_create_same_size(cairo_surface_t *s, cairo_content_t c); diff --git a/src/display/nr-arena-image.cpp b/src/display/nr-arena-image.cpp index 422b691b7..066133dde 100644 --- a/src/display/nr-arena-image.cpp +++ b/src/display/nr-arena-image.cpp @@ -39,6 +39,7 @@ static void nr_arena_image_finalize (NRObject *object); static unsigned int nr_arena_image_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset); static unsigned int nr_arena_image_render (cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); static NRArenaItem *nr_arena_image_pick (NRArenaItem *item, Geom::Point p, double delta, unsigned int sticky); +static Geom::Rect nr_arena_image_rect (NRArenaImage *image); static NRArenaItemClass *parent_class; @@ -80,12 +81,10 @@ static void nr_arena_image_init (NRArenaImage *image) { image->pixbuf = NULL; - image->x = image->y = 0.0; - image->width = 256.0; - image->height = 256.0; - - image->grid2px.setIdentity(); - image->px2grid.setIdentity(); + image->ctm.setIdentity(); + image->clipbox = Geom::Rect(); + image->ox = image->oy = 0.0; + image->sx = image->sy = 1.0; image->style = 0; image->render_opacity = TRUE; @@ -106,54 +105,24 @@ nr_arena_image_finalize (NRObject *object) static unsigned int nr_arena_image_update( NRArenaItem *item, NRRectL */*area*/, NRGC *gc, unsigned int /*state*/, unsigned int /*reset*/ ) { - Geom::Matrix grid2px; - // clear old bbox nr_arena_item_request_render(item); NRArenaImage *image = NR_ARENA_IMAGE (item); /* Copy affine */ - grid2px = gc->transform.inverse(); - double hscale, vscale; // todo: replace with Geom::Scale - if (image->pixbuf) { - hscale = gdk_pixbuf_get_width(image->pixbuf) / image->width; - vscale = gdk_pixbuf_get_height(image->pixbuf) / image->height; - } else { - hscale = 1.0; - vscale = 1.0; - } - - image->grid2px[0] = grid2px[0] * hscale; - image->grid2px[2] = grid2px[2] * hscale; - image->grid2px[4] = grid2px[4] * hscale; - image->grid2px[1] = grid2px[1] * vscale; - image->grid2px[3] = grid2px[3] * vscale; - image->grid2px[5] = grid2px[5] * vscale; - - image->grid2px[4] -= image->x * hscale; - image->grid2px[5] -= image->y * vscale; + image->ctm = gc->transform; /* Calculate bbox */ if (image->pixbuf) { NRRect bbox; - bbox.x0 = image->x; - bbox.y0 = image->y; - bbox.x1 = image->x + image->width; - bbox.y1 = image->y + image->height; + Geom::Rect r = nr_arena_image_rect(image) * gc->transform; - image->c00 = (Geom::Point(bbox.x0, bbox.y0) * gc->transform); - image->c01 = (Geom::Point(bbox.x0, bbox.y1) * gc->transform); - image->c10 = (Geom::Point(bbox.x1, bbox.y0) * gc->transform); - image->c11 = (Geom::Point(bbox.x1, bbox.y1) * gc->transform); - - nr_rect_d_matrix_transform (&bbox, &bbox, gc->transform); - - item->bbox.x0 = static_cast<NR::ICoord>(floor(bbox.x0)); // Floor gives the coordinate in which the point resides - item->bbox.y0 = static_cast<NR::ICoord>(floor(bbox.y0)); - item->bbox.x1 = static_cast<NR::ICoord>(ceil (bbox.x1)); // Ceil gives the first coordinate beyond the point - item->bbox.y1 = static_cast<NR::ICoord>(ceil (bbox.y1)); + item->bbox.x0 = floor(r.left()); // Floor gives the coordinate in which the point resides + item->bbox.y0 = floor(r.top()); + item->bbox.x1 = ceil(r.right()); // Ceil gives the first coordinate beyond the point + item->bbox.y1 = ceil(r.bottom()); } else { item->bbox.x0 = (int) gc->transform[4]; item->bbox.y0 = (int) gc->transform[5]; @@ -164,19 +133,12 @@ nr_arena_image_update( NRArenaItem *item, NRRectL */*area*/, NRGC *gc, unsigned return NR_ARENA_ITEM_STATE_ALL; } -#define FBITS 12 -#define b2i (image->grid2px) - static unsigned int nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int /*flags*/ ) { if (!ct) return item->state; -#if 0 - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - nr_arena_image_x_sample = prefs->getInt("/options/bitmapoversample/value", 1); - nr_arena_image_y_sample = nr_arena_image_x_sample; -#endif + bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); NRArenaImage *image = NR_ARENA_IMAGE (item); @@ -188,13 +150,25 @@ nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock // of the pixbuf. Fix this in Cairo and/or GDK. cairo_save(ct); cairo_translate(ct, -area->x0, -area->y0); + ink_cairo_transform(ct, image->ctm); + + cairo_new_path(ct); + cairo_rectangle(ct, image->clipbox.left(), image->clipbox.top(), + image->clipbox.width(), image->clipbox.height()); + cairo_clip(ct); + + cairo_translate(ct, image->ox, image->oy); + cairo_scale(ct, image->sx, image->sy); + gdk_cairo_set_source_pixbuf(ct, image->pixbuf, 0, 0); - cairo_pattern_t *p = cairo_get_source(ct); - ink_cairo_pattern_set_matrix(p, image->grid2px); + cairo_matrix_t tt; + Geom::Matrix total; + cairo_get_matrix(ct, &tt); + ink_matrix_to_2geom(total, tt); - Geom::Matrix total = item->ctm * image->grid2px.inverse(); if (total.expansionX() > 1.0 || total.expansionY() > 1.0) { + cairo_pattern_t *p = cairo_get_source(ct); cairo_pattern_set_filter(p, CAIRO_FILTER_NEAREST); } @@ -202,6 +176,11 @@ nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock cairo_restore(ct); } else { // outline; draw a rect instead + + cairo_save(ct); + cairo_translate(ct, -area->x0, -area->y0); + ink_cairo_transform(ct, image->ctm); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint32 rgba = prefs->getInt("/options/wireframecolors/images", 0xff0000ff); ink_cairo_set_source_rgba32(ct, rgba); @@ -209,11 +188,12 @@ nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock cairo_set_line_width(ct, 0.5); cairo_new_path(ct); - Geom::Point shift(area->x0, area->y0); - Geom::Point c00 = image->c00 - shift; - Geom::Point c01 = image->c01 - shift; - Geom::Point c11 = image->c11 - shift; - Geom::Point c10 = image->c10 - shift; + Geom::Rect r = nr_arena_image_rect (image); + + Geom::Point c00 = r.corner(0); + Geom::Point c01 = r.corner(3); + Geom::Point c11 = r.corner(2); + Geom::Point c10 = r.corner(1); cairo_move_to (ct, c00[Geom::X], c00[Geom::Y]); @@ -263,16 +243,22 @@ nr_arena_image_pick( NRArenaItem *item, Geom::Point p, double delta, unsigned in bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); if (outline) { + Geom::Rect r = nr_arena_image_rect (image); + + Geom::Point c00 = r.corner(0); + Geom::Point c01 = r.corner(3); + Geom::Point c11 = r.corner(2); + Geom::Point c10 = r.corner(1); // frame - if (distance_to_segment (p, image->c00, image->c10) < delta) return item; - if (distance_to_segment (p, image->c10, image->c11) < delta) return item; - if (distance_to_segment (p, image->c11, image->c01) < delta) return item; - if (distance_to_segment (p, image->c01, image->c00) < delta) return item; + if (distance_to_segment (p, c00, c10) < delta) return item; + if (distance_to_segment (p, c10, c11) < delta) return item; + if (distance_to_segment (p, c11, c01) < delta) return item; + if (distance_to_segment (p, c01, c00) < delta) return item; // diagonals - if (distance_to_segment (p, image->c00, image->c11) < delta) return item; - if (distance_to_segment (p, image->c10, image->c01) < delta) return item; + if (distance_to_segment (p, c00, c11) < delta) return item; + if (distance_to_segment (p, c10, c01) < delta) return item; return NULL; @@ -282,9 +268,17 @@ nr_arena_image_pick( NRArenaItem *item, Geom::Point p, double delta, unsigned in int const width = gdk_pixbuf_get_width(image->pixbuf); int const height = gdk_pixbuf_get_height(image->pixbuf); int const rowstride = gdk_pixbuf_get_rowstride(image->pixbuf); - Geom::Point tp = p * image->grid2px; - int const ix = (int)(tp[Geom::X]); - int const iy = (int)(tp[Geom::Y]); + + Geom::Point tp = p * image->ctm.inverse(); + Geom::Rect r = nr_arena_image_rect(image); + + if (!r.contains(tp)) + return NULL; + + double vw = width * image->sx; + double vh = height * image->sy; + int ix = floor((tp[Geom::X] - image->ox) / vw * width); + int iy = floor((tp[Geom::Y] - image->oy) / vh * height); if ((ix < 0) || (iy < 0) || (ix >= width) || (iy >= height)) return NULL; @@ -295,6 +289,26 @@ nr_arena_image_pick( NRArenaItem *item, Geom::Point p, double delta, unsigned in } } +Geom::Rect +nr_arena_image_rect (NRArenaImage *image) +{ + Geom::Rect r = image->clipbox; + + if (image->pixbuf) { + double pw = gdk_pixbuf_get_width(image->pixbuf); + double ph = gdk_pixbuf_get_height(image->pixbuf); + double vw = pw * image->sx; + double vh = ph * image->sy; + Geom::Point p(image->ox, image->oy); + Geom::Point wh(vw, vh); + Geom::Rect view(p, p+wh); + Geom::OptRect res = Geom::intersect(r, view); + r = res ? *res : r; + } + + return r; +} + /* Utility */ void @@ -316,15 +330,36 @@ nr_arena_image_set_pixbuf (NRArenaImage *image, GdkPixbuf *pb) } void -nr_arena_image_set_geometry (NRArenaImage *image, double x, double y, double width, double height) +nr_arena_image_set_clipbox (NRArenaImage *image, Geom::Rect const &clip) +{ + nr_return_if_fail (image != NULL); + nr_return_if_fail (NR_IS_ARENA_IMAGE (image)); + + image->clipbox = clip; + + nr_arena_item_request_update (NR_ARENA_ITEM (image), NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +void +nr_arena_image_set_origin (NRArenaImage *image, Geom::Point const &origin) +{ + nr_return_if_fail (image != NULL); + nr_return_if_fail (NR_IS_ARENA_IMAGE (image)); + + image->ox = origin[Geom::X]; + image->oy = origin[Geom::Y]; + + nr_arena_item_request_update (NR_ARENA_ITEM (image), NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +void +nr_arena_image_set_scale (NRArenaImage *image, double sx, double sy) { nr_return_if_fail (image != NULL); nr_return_if_fail (NR_IS_ARENA_IMAGE (image)); - image->x = x; - image->y = y; - image->width = width; - image->height = height; + image->sx = sx; + image->sy = sy; nr_arena_item_request_update (NR_ARENA_ITEM (image), NR_ARENA_ITEM_STATE_ALL, FALSE); } diff --git a/src/display/nr-arena-image.h b/src/display/nr-arena-image.h index c2a3b805c..76ff23c29 100644 --- a/src/display/nr-arena-image.h +++ b/src/display/nr-arena-image.h @@ -14,6 +14,7 @@ */ #include <gdk-pixbuf/gdk-pixbuf.h> +#include <2geom/rect.h> #include "nr-arena-item.h" #include "style.h" @@ -26,14 +27,10 @@ NRType nr_arena_image_get_type (void); struct NRArenaImage : public NRArenaItem { GdkPixbuf *pixbuf; - double x, y; - double width, height; - - Geom::Point c00, c01, c11, c10; // all 4 corners of the image, for outline mode rect - - /* From GRID to PIXELS */ - Geom::Matrix grid2px; - Geom::Matrix px2grid; + Geom::Matrix ctm; + Geom::Rect clipbox; + double ox, oy; + double sx, sy; SPStyle *style; @@ -49,9 +46,10 @@ struct NRArenaImageClass { }; void nr_arena_image_set_pixbuf (NRArenaImage *image, GdkPixbuf *pb); -void nr_arena_image_set_geometry (NRArenaImage *image, double x, double y, double width, double height); void nr_arena_image_set_style (NRArenaImage *image, SPStyle *style); - +void nr_arena_image_set_clipbox (NRArenaImage *image, Geom::Rect const &clip); +void nr_arena_image_set_origin (NRArenaImage *image, Geom::Point const &origin); +void nr_arena_image_set_scale (NRArenaImage *image, double sx, double sy); #endif diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 32ba3f021..b383512f5 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -19,6 +19,7 @@ #include <png.h> #include <cstring> +#include <algorithm> #include <string> #include <libnr/nr-matrix-fns.h> #include <libnr/nr-matrix-ops.h> @@ -94,6 +95,7 @@ static void sp_image_set_curve(SPImage *image); static GdkPixbuf *sp_image_repr_read_image( time_t& modTime, gchar*& pixPath, const gchar *href, const gchar *absref, const gchar *base ); static GdkPixbuf *sp_image_pixbuf_force_rgba (GdkPixbuf * pixbuf); +static void sp_image_update_arenaitem (SPImage *img, NRArenaImage *ai); static void sp_image_update_canvas_image (SPImage *image); static GdkPixbuf * sp_image_repr_read_dataURI (const gchar * uri_data); static GdkPixbuf * sp_image_repr_read_b64 (const gchar * uri_data); @@ -609,15 +611,9 @@ static void sp_image_init( SPImage *image ) image->width.unset(); image->height.unset(); image->aspect_align = SP_ASPECT_NONE; - - image->trimx = 0; - image->trimy = 0; - image->trimwidth = 0; - image->trimheight = 0; - image->viewx = 0; - image->viewy = 0; - image->viewwidth = 0; - image->viewheight = 0; + image->clipbox = Geom::Rect(); + image->sx = image->sy = 1.0; + image->ox = image->oy = 0.0; image->curve = NULL; @@ -924,13 +920,33 @@ sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags) } } } + + if (image->pixbuf) { + /* fixme: We are slightly violating spec here (Lauris) */ + if (!image->width._set) { + image->width.computed = gdk_pixbuf_get_width(image->pixbuf); + } + if (!image->height._set) { + image->height.computed = gdk_pixbuf_get_height(image->pixbuf); + } + } + + Geom::Point p(image->x.computed, image->y.computed); + Geom::Point wh(image->width.computed, image->height.computed); + image->clipbox = Geom::Rect(p, p + wh); + + image->ox = image->x.computed; + image->oy = image->y.computed; + + int pixwidth = gdk_pixbuf_get_width (image->pixbuf); + int pixheight = gdk_pixbuf_get_height (image->pixbuf); + + image->sx = image->width.computed / pixwidth; + image->sy = image->height.computed / pixheight; + // preserveAspectRatio calculate bounds / clipping rectangle -- EAF if (image->pixbuf && (image->aspect_align != SP_ASPECT_NONE)) { - int imagewidth, imageheight; - double x,y; - - imagewidth = gdk_pixbuf_get_width (image->pixbuf); - imageheight = gdk_pixbuf_get_height (image->pixbuf); + double x, y; switch (image->aspect_align) { case SP_ASPECT_XMIN_YMIN: @@ -976,43 +992,19 @@ sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags) } if (image->aspect_clip == SP_ASPECT_SLICE) { - image->viewx = image->x.computed; - image->viewy = image->y.computed; - image->viewwidth = image->width.computed; - image->viewheight = image->height.computed; - if ((imagewidth*image->height.computed)>(image->width.computed*imageheight)) { - // Pixels aspect is wider than bounding box - image->trimheight = imageheight; - image->trimwidth = static_cast<int>(static_cast<double>(imageheight) * image->width.computed / image->height.computed); - image->trimy = 0; - image->trimx = static_cast<int>(static_cast<double>(imagewidth - image->trimwidth) * x); - } else { - // Pixels aspect is taller than bounding box - image->trimwidth = imagewidth; - image->trimheight = static_cast<int>(static_cast<double>(imagewidth) * image->height.computed / image->width.computed); - image->trimx = 0; - image->trimy = static_cast<int>(static_cast<double>(imageheight - image->trimheight) * y); - } + double scale = std::max(image->sx, image->sy); + image->sx = scale; + image->sy = scale; } else { - // Otherwise, assume SP_ASPECT_MEET - image->trimx = 0; - image->trimy = 0; - image->trimwidth = imagewidth; - image->trimheight = imageheight; - if ((imagewidth*image->height.computed)>(image->width.computed*imageheight)) { - // Pixels aspect is wider than bounding boz - image->viewwidth = image->width.computed; - image->viewheight = image->viewwidth * imageheight / imagewidth; - image->viewx=image->x.computed; - image->viewy=(image->height.computed - image->viewheight) * y + image->y.computed; - } else { - // Pixels aspect is taller than bounding box - image->viewheight = image->height.computed; - image->viewwidth = image->viewheight * imagewidth / imageheight; - image->viewy=image->y.computed; - image->viewx=(image->width.computed - image->viewwidth) * x + image->x.computed; - } + double scale = std::min(image->sx, image->sy); + image->sx = scale; + image->sy = scale; } + + double vw = pixwidth * image->sx; + double vh = pixheight * image->sy; + image->ox += x * (image->width.computed - vw); + image->oy += y * (image->height.computed - vh); } sp_image_update_canvas_image ((SPImage *) object); } @@ -1100,26 +1092,35 @@ sp_image_print (SPItem *item, SPPrintContext *ctx) int rs = gdk_pixbuf_get_rowstride(image->pixbuf); int pixskip = gdk_pixbuf_get_n_channels(image->pixbuf) * gdk_pixbuf_get_bits_per_sample(image->pixbuf) / 8; - Geom::Matrix t; if (image->aspect_align == SP_ASPECT_NONE) { - /* fixme: (Lauris) */ + Geom::Matrix t; Geom::Translate tp(image->x.computed, image->y.computed); Geom::Scale s(image->width.computed, -image->height.computed); Geom::Translate ti(0.0, -1.0); t = s * tp; t = ti * t; + sp_print_image_R8G8B8A8_N(ctx, px, w, h, rs, &t, SP_OBJECT_STYLE (item)); } else { // preserveAspectRatio - Geom::Translate tp(image->viewx, image->viewy); - Geom::Scale s(image->viewwidth, -image->viewheight); + double vw = image->width.computed / image->sx; + double vh = image->height.computed / image->sy; + + int trimwidth = std::min<int>(w, ceil(image->width.computed / vw * w)); + int trimheight = std::min<int>(h, ceil(image->height.computed / vh * h)); + int trimx = std::max<int>(0, floor((image->x.computed - image->ox) / vw * w)); + int trimy = std::max<int>(0, floor((image->y.computed - image->oy) / vh * h)); + + double vx = std::max<double>(image->ox, image->x.computed); + double vy = std::max<double>(image->oy, image->y.computed); + double vcw = std::min<double>(image->width.computed, vw); + double vch = std::min<double>(image->height.computed, vh); + + Geom::Matrix t; + Geom::Translate tp(vx, vy); + Geom::Scale s(vcw, -vch); Geom::Translate ti(0.0, -1.0); t = s * tp; t = ti * t; - } - - if (image->aspect_align == SP_ASPECT_NONE) { - sp_print_image_R8G8B8A8_N(ctx, px, w, h, rs, &t, SP_OBJECT_STYLE (item)); - } else { // preserveAspectRatio - sp_print_image_R8G8B8A8_N(ctx, px + image->trimx*pixskip + image->trimy*rs, image->trimwidth, image->trimheight, rs, &t, SP_OBJECT_STYLE(item)); + sp_print_image_R8G8B8A8_N(ctx, px + trimx*pixskip + trimy*rs, trimwidth, trimheight, rs, &t, SP_OBJECT_STYLE(item)); } } } @@ -1154,36 +1155,7 @@ sp_image_show (SPItem *item, NRArena *arena, unsigned int /*key*/, unsigned int SPImage * image = SP_IMAGE(item); NRArenaItem *ai = NRArenaImage::create(arena); - if (image->pixbuf) { - nr_arena_image_set_pixbuf(NR_ARENA_IMAGE(ai), image->pixbuf); -#if 0 - int pixskip = gdk_pixbuf_get_n_channels(image->pixbuf) * gdk_pixbuf_get_bits_per_sample(image->pixbuf) / 8; - int rs = gdk_pixbuf_get_rowstride(image->pixbuf); - nr_arena_image_set_style(NR_ARENA_IMAGE(ai), SP_OBJECT_STYLE(SP_OBJECT(item))); - if (image->aspect_align == SP_ASPECT_NONE) { - nr_arena_image_set_pixels(NR_ARENA_IMAGE(ai), - gdk_pixbuf_get_pixels(image->pixbuf), - gdk_pixbuf_get_width(image->pixbuf), - gdk_pixbuf_get_height(image->pixbuf), - rs); - } else { // preserveAspectRatio - nr_arena_image_set_pixels(NR_ARENA_IMAGE(ai), - gdk_pixbuf_get_pixels(image->pixbuf) + image->trimx*pixskip + image->trimy*rs, - image->trimwidth, - image->trimheight, - rs); - } -#endif - } else { - nr_arena_image_set_pixbuf(NR_ARENA_IMAGE(ai), NULL); - } - - // TODO: reenable preserveAspectRatio - //if (image->aspect_align == SP_ASPECT_NONE) { - nr_arena_image_set_geometry(NR_ARENA_IMAGE(ai), image->x.computed, image->y.computed, image->width.computed, image->height.computed); - //} else { // preserveAspectRatio - // nr_arena_image_set_geometry(NR_ARENA_IMAGE(ai), image->viewx, image->viewy, image->viewwidth, image->viewheight); - //} + sp_image_update_arenaitem(image, NR_ARENA_IMAGE(ai)); return ai; } @@ -1296,39 +1268,22 @@ sp_image_pixbuf_force_rgba (GdkPixbuf * pixbuf) /* We assert that realpixbuf is either NULL or identical size to pixbuf */ static void +sp_image_update_arenaitem (SPImage *image, NRArenaImage *ai) +{ + nr_arena_image_set_style(ai, SP_OBJECT_STYLE(SP_OBJECT(image))); + nr_arena_image_set_pixbuf(ai, image->pixbuf); + nr_arena_image_set_origin(ai, Geom::Point(image->ox, image->oy)); + nr_arena_image_set_scale(ai, image->sx, image->sy); + nr_arena_image_set_clipbox(ai, image->clipbox); +} + +static void sp_image_update_canvas_image (SPImage *image) { SPItem *item = SP_ITEM(image); - if (image->pixbuf) { - /* fixme: We are slightly violating spec here (Lauris) */ - if (!image->width._set) { - image->width.computed = gdk_pixbuf_get_width(image->pixbuf); - } - if (!image->height._set) { - image->height.computed = gdk_pixbuf_get_height(image->pixbuf); - } - } - for (SPItemView *v = item->display; v != NULL; v = v->next) { - nr_arena_image_set_style(NR_ARENA_IMAGE(v->arenaitem), SP_OBJECT_STYLE(SP_OBJECT(image))); - // TODO: reenable preserveAspectRatio - //if (image->aspect_align == SP_ASPECT_NONE) { - nr_arena_image_set_pixbuf(NR_ARENA_IMAGE(v->arenaitem), - image->pixbuf); - nr_arena_image_set_geometry(NR_ARENA_IMAGE(v->arenaitem), - image->x.computed, image->y.computed, - image->width.computed, image->height.computed); - /*} else { // preserveAspectRatio - nr_arena_image_set_pixels(NR_ARENA_IMAGE(v->arenaitem), - gdk_pixbuf_get_pixels(image->pixbuf) + image->trimx*pixskip + image->trimy*rs, - image->trimwidth, - image->trimheight, - rs); - nr_arena_image_set_geometry(NR_ARENA_IMAGE(v->arenaitem), - image->viewx, image->viewy, - image->viewwidth, image->viewheight); - }*/ + sp_image_update_arenaitem(image, NR_ARENA_IMAGE(v->arenaitem)); } } diff --git a/src/sp-image.h b/src/sp-image.h index 172cd7118..2d744fb12 100644 --- a/src/sp-image.h +++ b/src/sp-image.h @@ -39,12 +39,16 @@ struct SPImage : public SPItem { SVGLength width; SVGLength height; + Geom::Rect clipbox; + double sx, sy; + double ox, oy; + // Added by EAF /* preserveAspectRatio */ unsigned int aspect_align : 4; unsigned int aspect_clip : 1; - int trimx, trimy, trimwidth, trimheight; - double viewx, viewy, viewwidth, viewheight; + //int trimx, trimy, trimwidth, trimheight; + //double viewx, viewy, viewwidth, viewheight; SPCurve *curve; // This curve is at the image's boundary for snapping |
