X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsp-image.cpp;h=d535874e93c34d8ba69d0b91bb6fa1774704474e;hb=88013f5100c818a1b1c0d9d9cf773930373491cf;hp=961661fc6bf0bba063e1ffc6dea41f4b85b6587f;hpb=f76d92334c7aeccf565c8eb910f1df03c6b25e16;p=inkscape.git diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 961661fc6..d535874e9 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -21,6 +21,7 @@ //#define GDK_PIXBUF_ENABLE_BACKEND 1 //#include #include "display/nr-arena-image.h" +#include //Added for preserveAspectRatio support -- EAF #include "enums.h" @@ -30,10 +31,13 @@ #include "brokenimage.xpm" #include "document.h" #include "sp-image.h" +#include "sp-clippath.h" #include #include "xml/quote.h" #include +#include "libnr/nr-matrix-fns.h" + #include "io/sys.h" #include #if ENABLE_LCMS @@ -65,6 +69,8 @@ static gchar * sp_image_description (SPItem * item); static void sp_image_snappoints(SPItem const *item, SnapPointsIter p); static NRArenaItem *sp_image_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); static NR::Matrix sp_image_set_transform (SPItem *item, NR::Matrix const &xform); +static void sp_image_set_curve(SPImage *image); + GdkPixbuf *sp_image_repr_read_image (const gchar *href, const gchar *absref, const gchar *base); static GdkPixbuf *sp_image_pixbuf_force_rgba (GdkPixbuf * pixbuf); @@ -502,6 +508,7 @@ sp_image_init (SPImage *image) image->width.unset(); image->height.unset(); image->aspect_align = SP_ASPECT_NONE; + image->curve = NULL; } static void @@ -551,6 +558,10 @@ sp_image_release (SPObject *object) } #endif // ENABLE_LCMS + if (image->curve) { + image->curve = sp_curve_unref (image->curve); + } + if (((SPObjectClass *) parent_class)->release) ((SPObjectClass *) parent_class)->release (object); } @@ -676,6 +687,8 @@ sp_image_set (SPObject *object, unsigned int key, const gchar *value) ((SPObjectClass *) (parent_class))->set (object, key, value); break; } + + sp_image_set_curve(image); //creates a curve at the image's boundary for snapping } static void @@ -697,8 +710,8 @@ sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags) if (image->href) { GdkPixbuf *pixbuf; pixbuf = sp_image_repr_read_image ( - object->repr->attribute("xlink:href"), - object->repr->attribute("sodipodi:absref"), + object->repr->attribute("xlink:href"), + object->repr->attribute("sodipodi:absref"), doc->base); if (pixbuf) { pixbuf = sp_image_pixbuf_force_rgba (pixbuf); @@ -740,7 +753,7 @@ sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags) intent = INTENT_PERCEPTUAL; } cmsHPROFILE destProf = cmsCreate_sRGBProfile(); - cmsHTRANSFORM transf = cmsCreateTransform( prof, + cmsHTRANSFORM transf = cmsCreateTransform( prof, TYPE_RGBA_8, destProf, TYPE_RGBA_8, @@ -873,7 +886,6 @@ sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags) } } } - sp_image_update_canvas_image ((SPImage *) object); } @@ -1062,7 +1074,7 @@ sp_image_repr_read_image (const gchar *href, const gchar *absref, const gchar *b if (!docbase) docbase = "."; fullname = g_build_filename(docbase, filename, NULL); - // document base can be wrong (on the temporary doc when importing bitmap from a + // document base can be wrong (on the temporary doc when importing bitmap from a // different dir) or unset (when doc is not saved yet), so we check for base+href existence first, // and if it fails, we also try to use bare href regardless of its g_path_is_absolute if (g_file_test (fullname, G_FILE_TEST_EXISTS) && !g_file_test (fullname, G_FILE_TEST_IS_DIR)) { @@ -1070,7 +1082,7 @@ sp_image_repr_read_image (const gchar *href, const gchar *absref, const gchar *b g_free (fullname); if (pixbuf != NULL) return pixbuf; } - } + } /* try filename as absolute */ if (g_file_test (filename, G_FILE_TEST_EXISTS) && !g_file_test (filename, G_FILE_TEST_IS_DIR)) { @@ -1084,7 +1096,11 @@ sp_image_repr_read_image (const gchar *href, const gchar *absref, const gchar *b filename = absref; if (filename != NULL) { // using absref is outside of SVG rules, so we must at least warn the user - g_warning (" did not resolve to a valid image file (base dir is %s), now trying sodipodi:absref=\"%s\"", href, base, absref); + if ( base != NULL && href != NULL ) + g_warning (" did not resolve to a valid image file (base dir is %s), now trying sodipodi:absref=\"%s\"", href, base, absref); + else + g_warning ("xlink:href did not resolve to a valid image file, now trying sodipodi:absref=\"%s\"", absref); + pixbuf = Inkscape::IO::pixbuf_new_from_file( filename, NULL ); if (pixbuf != NULL) return pixbuf; } @@ -1160,9 +1176,30 @@ sp_image_update_canvas_image (SPImage *image) static void sp_image_snappoints(SPItem const *item, SnapPointsIter p) { - if (((SPItemClass *) parent_class)->snappoints) { - ((SPItemClass *) parent_class)->snappoints (item, p); - } + /* An image doesn't have any nodes to snap, but still we want to be able snap one image + to another. Therefore we will create some snappoints at the corner, similar to a rect. If + the image is rotated, then the snappoints will rotate with it. Again, just like a rect. + */ + + g_assert(item != NULL); + g_assert(SP_IS_IMAGE(item)); + + if (item->clip_ref->getObject()) { + //We are looking at a clipped image: do not return any snappoints, as these might be + //far far away from the visible part from the clipped image + } else { + // The image has not been clipped: return its corners, which might be rotated for example + SPImage &image = *SP_IMAGE(item); + double const x0 = image.x.computed; + double const y0 = image.y.computed; + double const x1 = x0 + image.width.computed; + double const y1 = y0 + image.height.computed; + NR::Matrix const i2d (sp_item_i2d_affine (item)); + *p = NR::Point(x0, y0) * i2d; + *p = NR::Point(x0, y1) * i2d; + *p = NR::Point(x1, y1) * i2d; + *p = NR::Point(x1, y0) * i2d; + } } /* @@ -1351,6 +1388,45 @@ sp_image_repr_read_b64 (const gchar * uri_data) return pixbuf; } +static void +sp_image_set_curve(SPImage *image) +{ + //create a curve at the image's boundary for snapping + if ((image->height.computed < 1e-18) || (image->width.computed < 1e-18) || (image->clip_ref->getObject())) { + if (image->curve) { + image->curve = sp_curve_unref(image->curve); + } + return; + } + + NRRect rect; + sp_image_bbox(image, &rect, NR::identity(), 0); + NR::Maybe rect2 = rect.upgrade(); + SPCurve *c = sp_curve_new_from_rect(rect2); + + if (image->curve) { + image->curve = sp_curve_unref(image->curve); + } + + if (c) { + image->curve = sp_curve_ref(c); + } + + sp_curve_unref(c); +} + +/** + * Return duplicate of curve (if any exists) or NULL if there is no curve + */ +SPCurve * +sp_image_get_curve (SPImage *image) +{ + if (image->curve) { + return sp_curve_copy(image->curve); + } + return NULL; +} + /* Local Variables: mode:c++