From d41eb702951c69bfd362e70bd072a869bf73967a Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 16 Jan 2014 16:05:23 -0500 Subject: Clean up sp-image's read_image, remove duplicate code (bzr r12942) --- src/sp-image.cpp | 57 ++++++++++++++------------------------------------------ 1 file changed, 14 insertions(+), 43 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 8f7a60ca6..9044257f4 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -649,56 +649,27 @@ Inkscape::DrawingItem* SPImage::show(Inkscape::Drawing &drawing, unsigned int /* Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base) { Inkscape::Pixbuf *inkpb = 0; - gchar const *filename = href; - + if (filename != NULL) { if (strncmp (filename,"file:",5) == 0) { - gchar *fullname = g_filename_from_uri(filename, NULL, NULL); - if (fullname) { - inkpb = Inkscape::Pixbuf::create_from_file(fullname); - g_free(fullname); - if (inkpb != NULL) { - return inkpb; - } - } + filename = g_filename_from_uri(filename, NULL, NULL); } else if (strncmp (filename,"data:",5) == 0) { /* data URI - embedded image */ filename += 5; - inkpb = Inkscape::Pixbuf::create_from_data_uri(filename); - if (inkpb != NULL) { - return inkpb; - } - } else { - - if (!g_path_is_absolute (filename)) { - /* try to load from relative pos combined with document base*/ - const gchar *docbase = base; - if (!docbase) { - docbase = "."; - } - gchar *fullname = g_build_filename(docbase, filename, NULL); - - // 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)) { - inkpb = Inkscape::Pixbuf::create_from_file(fullname); - if (inkpb != NULL) { - g_free (fullname); - return inkpb; - } - } - g_free (fullname); - } + } else if (!g_path_is_absolute (filename)) { + /* try to load from relative pos combined with document base*/ + const gchar *docbase = base; + if (!docbase) docbase = "."; + filename = g_build_filename(docbase, filename, NULL); + } + } - /* try filename as absolute */ - if (g_file_test (filename, G_FILE_TEST_EXISTS) && !g_file_test (filename, G_FILE_TEST_IS_DIR)) { - inkpb = Inkscape::Pixbuf::create_from_file(filename); - if (inkpb != NULL) { - return inkpb; - } - } + if (filename && g_file_test(filename, G_FILE_TEST_EXISTS) ) { + inkpb = Inkscape::Pixbuf::create_from_file(filename); + if (inkpb != NULL) { + // g_free filename? + return inkpb; } } -- cgit v1.2.3 From 47edb3f774f4eca0716960c66cdcdea3954c86b1 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 16 Jan 2014 22:31:43 -0500 Subject: More cleaning of the image tag handler and seperate filename from load. (bzr r12945) --- src/sp-image.cpp | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 9044257f4..f4995ce31 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -24,6 +24,7 @@ #include <2geom/rect.h> #include <2geom/transforms.h> #include +#include #include "display/drawing-image.h" #include "display/cairo-utils.h" @@ -75,7 +76,7 @@ static void sp_image_set_curve(SPImage *image); -static Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base ); +gchar const *sp_image_repr_read_filename(gchar const *href, gchar const *absref, gchar const *base ); static void sp_image_update_arenaitem (SPImage *img, Inkscape::DrawingImage *ai); static void sp_image_update_canvas_image (SPImage *image); @@ -333,11 +334,26 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { if (this->href) { Inkscape::Pixbuf *pixbuf = NULL; - pixbuf = sp_image_repr_read_image ( + + gchar const* filename = sp_image_repr_read_filename ( this->getRepr()->attribute("xlink:href"), this->getRepr()->attribute("sodipodi:absref"), doc->getBase()); - + + if(filename && g_str_has_suffix(filename, ".svg")) { + // TODO: We want to deal with svg images properly. This + // space allows us to do so later. + g_warning("Including svg images tags is not yet supported."); + } else if (filename) { + pixbuf = Inkscape::Pixbuf::create_from_file(filename); + } else { + /* Nope: We do not find any valid pixmap file :-( */ + pixbuf = new Inkscape::Pixbuf( + gdk_pixbuf_new_from_xpm_data((const gchar **) brokenimage_xpm)); + + /* If the xpm doesn't load, our libraries are broken */ + g_assert (pixbuf != NULL); + } if (pixbuf) { // BLIP #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -646,9 +662,8 @@ Inkscape::DrawingItem* SPImage::show(Inkscape::Drawing &drawing, unsigned int /* return ai; } -Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base) +gchar const *sp_image_repr_read_filename(gchar const *href, gchar const *absref, gchar const *base) { - Inkscape::Pixbuf *inkpb = 0; gchar const *filename = href; if (filename != NULL) { @@ -666,37 +681,20 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre } if (filename && g_file_test(filename, G_FILE_TEST_EXISTS) ) { - inkpb = Inkscape::Pixbuf::create_from_file(filename); - if (inkpb != NULL) { - // g_free filename? - return inkpb; - } + return filename; } /* at last try to load from sp absolute path name */ - filename = absref; - if (filename != NULL) { + if (absref != NULL && g_file_test(absref, G_FILE_TEST_EXISTS)) { // using absref is outside of SVG rules, so we must at least warn the user 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); } - - inkpb = Inkscape::Pixbuf::create_from_file(filename); - if (inkpb != NULL) { - return inkpb; - } + return absref; } - /* Nope: We do not find any valid pixmap file :-( */ - GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **) brokenimage_xpm); - inkpb = new Inkscape::Pixbuf(pixbuf); - - /* It should be included xpm, so if it still does not does load, */ - /* our libraries are broken */ - g_assert (inkpb != NULL); - - return inkpb; + return NULL; } /* We assert that realpixbuf is either NULL or identical size to pixbuf */ -- cgit v1.2.3 From 8ce1d4c9f4cad86fb0b1f63c6b25838c8c6d640d Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 17 Jan 2014 23:51:59 -0500 Subject: Fix missing embeded image condition, kindly caught by suv in bug #1270334 Fixed bugs: - https://launchpad.net/bugs/1270334 (bzr r12954) --- src/sp-image.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index f4995ce31..b08d6f9b0 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -340,13 +340,18 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { this->getRepr()->attribute("sodipodi:absref"), doc->getBase()); - if(filename && g_str_has_suffix(filename, ".svg")) { + Inkscape::Pixbuf::create_from_data_uri(filename); + if (strncmp (filename,"data:", 5) == 0) { + filename += 5; + pixbuf = Inkscape::Pixbuf::create_from_data_uri(filename); + } else if(filename && g_str_has_suffix(filename, ".svg")) { // TODO: We want to deal with svg images properly. This // space allows us to do so later. g_warning("Including svg images tags is not yet supported."); } else if (filename) { pixbuf = Inkscape::Pixbuf::create_from_file(filename); - } else { + } + if(!pixbuf) { /* Nope: We do not find any valid pixmap file :-( */ pixbuf = new Inkscape::Pixbuf( gdk_pixbuf_new_from_xpm_data((const gchar **) brokenimage_xpm)); @@ -671,7 +676,7 @@ gchar const *sp_image_repr_read_filename(gchar const *href, gchar const *absref, filename = g_filename_from_uri(filename, NULL, NULL); } else if (strncmp (filename,"data:",5) == 0) { /* data URI - embedded image */ - filename += 5; + return filename; } else if (!g_path_is_absolute (filename)) { /* try to load from relative pos combined with document base*/ const gchar *docbase = base; -- cgit v1.2.3 From 24b5b970fd4e6fadce881db84aa9f40bf81183d8 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 24 Jan 2014 20:05:47 -0500 Subject: A partial refactor of sp-image.cpp, expect more. (bzr r12978) --- src/sp-image.cpp | 89 +++++++++++++++++++++----------------------------------- 1 file changed, 33 insertions(+), 56 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index b08d6f9b0..f1ea737ff 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -76,7 +76,6 @@ static void sp_image_set_curve(SPImage *image); -gchar const *sp_image_repr_read_filename(gchar const *href, gchar const *absref, gchar const *base ); static void sp_image_update_arenaitem (SPImage *img, Inkscape::DrawingImage *ai); static void sp_image_update_canvas_image (SPImage *image); @@ -170,8 +169,7 @@ void SPImage::release() { this->href = NULL; } - delete this->pixbuf; - this->pixbuf = NULL; + this->clear_image(); #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) if (this->color_profile) { @@ -329,29 +327,31 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { SPItem::update(ctx, flags); if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) { - delete this->pixbuf; - this->pixbuf = NULL; + this->clear_image(); if (this->href) { Inkscape::Pixbuf *pixbuf = NULL; + gchar const* uri = this->getRepr()->attribute("xlink:href"); + + if(!uri) { + g_warning("Image tag has no valid href: %s", this->getId()); - gchar const* filename = sp_image_repr_read_filename ( - this->getRepr()->attribute("xlink:href"), - this->getRepr()->attribute("sodipodi:absref"), - doc->getBase()); - - Inkscape::Pixbuf::create_from_data_uri(filename); - if (strncmp (filename,"data:", 5) == 0) { - filename += 5; - pixbuf = Inkscape::Pixbuf::create_from_data_uri(filename); - } else if(filename && g_str_has_suffix(filename, ".svg")) { - // TODO: We want to deal with svg images properly. This - // space allows us to do so later. - g_warning("Including svg images tags is not yet supported."); - } else if (filename) { - pixbuf = Inkscape::Pixbuf::create_from_file(filename); + } else if (strncmp (uri, "data:", 5) == 0) { + uri += 5; + pixbuf = Inkscape::Pixbuf::create_from_data_uri(uri); + + } else if(g_str_has_suffix(uri, ".svg")) { + SPDocument *doc = this->document->createChildDoc(uri); + if(doc) { + this->child = SP_ITEM(doc); + g_warning("Loaded document: %s", uri); + } else { + g_warning("Could not load svg for image tag: %s",this->getId()); + } + } else { + pixbuf = Inkscape::Pixbuf::create_from_file(uri); } - if(!pixbuf) { + if(!pixbuf && !this->child) { /* Nope: We do not find any valid pixmap file :-( */ pixbuf = new Inkscape::Pixbuf( gdk_pixbuf_new_from_xpm_data((const gchar **) brokenimage_xpm)); @@ -527,6 +527,18 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { sp_image_update_canvas_image ((SPImage *) this); } +// Remove references to image or child objects. +void SPImage::clear_image() { + if(this->pixbuf) { + delete this->pixbuf; + this->pixbuf = NULL; + } + if(this->child) { + this->detach(this->child); + this->child = NULL; + } +} + void SPImage::modified(unsigned int flags) { // SPItem::onModified(flags); @@ -667,41 +679,6 @@ Inkscape::DrawingItem* SPImage::show(Inkscape::Drawing &drawing, unsigned int /* return ai; } -gchar const *sp_image_repr_read_filename(gchar const *href, gchar const *absref, gchar const *base) -{ - gchar const *filename = href; - - if (filename != NULL) { - if (strncmp (filename,"file:",5) == 0) { - filename = g_filename_from_uri(filename, NULL, NULL); - } else if (strncmp (filename,"data:",5) == 0) { - /* data URI - embedded image */ - return filename; - } else if (!g_path_is_absolute (filename)) { - /* try to load from relative pos combined with document base*/ - const gchar *docbase = base; - if (!docbase) docbase = "."; - filename = g_build_filename(docbase, filename, NULL); - } - } - - if (filename && g_file_test(filename, G_FILE_TEST_EXISTS) ) { - return filename; - } - - /* at last try to load from sp absolute path name */ - if (absref != NULL && g_file_test(absref, G_FILE_TEST_EXISTS)) { - // using absref is outside of SVG rules, so we must at least warn the user - 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); - } - return absref; - } - return NULL; -} - /* We assert that realpixbuf is either NULL or identical size to pixbuf */ static void sp_image_update_arenaitem (SPImage *image, Inkscape::DrawingImage *ai) -- cgit v1.2.3 From a9e16718924f28cf5e55706946720b2cc44a409d Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 29 Jan 2014 16:55:32 -0500 Subject: Revert sp-image until the refactoring takes. (bzr r12984) --- src/sp-image.cpp | 135 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 43 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index f1ea737ff..8f7a60ca6 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -24,7 +24,6 @@ #include <2geom/rect.h> #include <2geom/transforms.h> #include -#include #include "display/drawing-image.h" #include "display/cairo-utils.h" @@ -76,6 +75,7 @@ static void sp_image_set_curve(SPImage *image); +static Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base ); static void sp_image_update_arenaitem (SPImage *img, Inkscape::DrawingImage *ai); static void sp_image_update_canvas_image (SPImage *image); @@ -169,7 +169,8 @@ void SPImage::release() { this->href = NULL; } - this->clear_image(); + delete this->pixbuf; + this->pixbuf = NULL; #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) if (this->color_profile) { @@ -327,38 +328,16 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { SPItem::update(ctx, flags); if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) { - this->clear_image(); + delete this->pixbuf; + this->pixbuf = NULL; if (this->href) { Inkscape::Pixbuf *pixbuf = NULL; - gchar const* uri = this->getRepr()->attribute("xlink:href"); - - if(!uri) { - g_warning("Image tag has no valid href: %s", this->getId()); - - } else if (strncmp (uri, "data:", 5) == 0) { - uri += 5; - pixbuf = Inkscape::Pixbuf::create_from_data_uri(uri); - - } else if(g_str_has_suffix(uri, ".svg")) { - SPDocument *doc = this->document->createChildDoc(uri); - if(doc) { - this->child = SP_ITEM(doc); - g_warning("Loaded document: %s", uri); - } else { - g_warning("Could not load svg for image tag: %s",this->getId()); - } - } else { - pixbuf = Inkscape::Pixbuf::create_from_file(uri); - } - if(!pixbuf && !this->child) { - /* Nope: We do not find any valid pixmap file :-( */ - pixbuf = new Inkscape::Pixbuf( - gdk_pixbuf_new_from_xpm_data((const gchar **) brokenimage_xpm)); - - /* If the xpm doesn't load, our libraries are broken */ - g_assert (pixbuf != NULL); - } + pixbuf = sp_image_repr_read_image ( + this->getRepr()->attribute("xlink:href"), + this->getRepr()->attribute("sodipodi:absref"), + doc->getBase()); + if (pixbuf) { // BLIP #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -527,18 +506,6 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { sp_image_update_canvas_image ((SPImage *) this); } -// Remove references to image or child objects. -void SPImage::clear_image() { - if(this->pixbuf) { - delete this->pixbuf; - this->pixbuf = NULL; - } - if(this->child) { - this->detach(this->child); - this->child = NULL; - } -} - void SPImage::modified(unsigned int flags) { // SPItem::onModified(flags); @@ -679,6 +646,88 @@ Inkscape::DrawingItem* SPImage::show(Inkscape::Drawing &drawing, unsigned int /* return ai; } +Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base) +{ + Inkscape::Pixbuf *inkpb = 0; + + gchar const *filename = href; + + if (filename != NULL) { + if (strncmp (filename,"file:",5) == 0) { + gchar *fullname = g_filename_from_uri(filename, NULL, NULL); + if (fullname) { + inkpb = Inkscape::Pixbuf::create_from_file(fullname); + g_free(fullname); + if (inkpb != NULL) { + return inkpb; + } + } + } else if (strncmp (filename,"data:",5) == 0) { + /* data URI - embedded image */ + filename += 5; + inkpb = Inkscape::Pixbuf::create_from_data_uri(filename); + if (inkpb != NULL) { + return inkpb; + } + } else { + + if (!g_path_is_absolute (filename)) { + /* try to load from relative pos combined with document base*/ + const gchar *docbase = base; + if (!docbase) { + docbase = "."; + } + gchar *fullname = g_build_filename(docbase, filename, NULL); + + // 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)) { + inkpb = Inkscape::Pixbuf::create_from_file(fullname); + if (inkpb != NULL) { + g_free (fullname); + return inkpb; + } + } + g_free (fullname); + } + + /* try filename as absolute */ + if (g_file_test (filename, G_FILE_TEST_EXISTS) && !g_file_test (filename, G_FILE_TEST_IS_DIR)) { + inkpb = Inkscape::Pixbuf::create_from_file(filename); + if (inkpb != NULL) { + return inkpb; + } + } + } + } + + /* at last try to load from sp absolute path name */ + filename = absref; + if (filename != NULL) { + // using absref is outside of SVG rules, so we must at least warn the user + 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); + } + + inkpb = Inkscape::Pixbuf::create_from_file(filename); + if (inkpb != NULL) { + return inkpb; + } + } + /* Nope: We do not find any valid pixmap file :-( */ + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **) brokenimage_xpm); + inkpb = new Inkscape::Pixbuf(pixbuf); + + /* It should be included xpm, so if it still does not does load, */ + /* our libraries are broken */ + g_assert (inkpb != NULL); + + return inkpb; +} + /* We assert that realpixbuf is either NULL or identical size to pixbuf */ static void sp_image_update_arenaitem (SPImage *image, Inkscape::DrawingImage *ai) -- cgit v1.2.3 From 7dd239eed97761b22ef635b6896a8f65c4939462 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 6 Feb 2014 15:29:15 +0100 Subject: Added new base class to handle viewBox and preserveAspectRatio. Updated sp-root, sp-symbol, sp-image, sp-pattern, marker to use new class. Fixed some viewport issues when % used. (bzr r13002) --- src/sp-image.cpp | 347 ++++++++++++++++++++++--------------------------------- 1 file changed, 136 insertions(+), 211 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 8f7a60ca6..5f630f7b7 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -119,14 +119,12 @@ SPObject* createImage() { bool imageRegistered = SPFactory::instance().registerObject("svg:image", createImage); } -SPImage::SPImage() : SPItem() { - this->aspect_clip = 0; +SPImage::SPImage() : SPItem(), SPViewBox() { this->x.unset(); this->y.unset(); this->width.unset(); this->height.unset(); - this->aspect_align = SP_ASPECT_NONE; this->clipbox = Geom::Rect(); this->sx = this->sy = 1.0; this->ox = this->oy = 0.0; @@ -195,8 +193,8 @@ void SPImage::set(unsigned int key, const gchar* value) { break; case SP_ATTR_X: - if (!this->x.readAbsolute(value)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + /* ex, em not handled correctly. */ + if (!this->x.read(value)) { this->x.unset(); } @@ -204,8 +202,8 @@ void SPImage::set(unsigned int key, const gchar* value) { break; case SP_ATTR_Y: - if (!this->y.readAbsolute(value)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + /* ex, em not handled correctly. */ + if (!this->y.read(value)) { this->y.unset(); } @@ -213,8 +211,8 @@ void SPImage::set(unsigned int key, const gchar* value) { break; case SP_ATTR_WIDTH: - if (!this->width.readAbsolute(value)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + /* ex, em not handled correctly. */ + if (!this->width.read(value)) { this->width.unset(); } @@ -222,8 +220,8 @@ void SPImage::set(unsigned int key, const gchar* value) { break; case SP_ATTR_HEIGHT: - if (!this->height.readAbsolute(value)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + /* ex, em not handled correctly. */ + if (!this->height.read(value)) { this->height.unset(); } @@ -231,67 +229,8 @@ void SPImage::set(unsigned int key, const gchar* value) { break; case SP_ATTR_PRESERVEASPECTRATIO: - /* Do setup before, so we can use break to escape */ - this->aspect_align = SP_ASPECT_NONE; - this->aspect_clip = SP_ASPECT_MEET; + set_preserveAspectRatio( value ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - - if (value) { - int len; - gchar c[256]; - const gchar *p, *e; - unsigned int align, clip; - p = value; - while (*p && *p == 32) p += 1; - if (!*p) break; - e = p; - while (*e && *e != 32) e += 1; - len = e - p; - if (len > 8) break; - memcpy (c, value, len); - c[len] = 0; - /* Now the actual part */ - if (!strcmp (c, "none")) { - align = SP_ASPECT_NONE; - } else if (!strcmp (c, "xMinYMin")) { - align = SP_ASPECT_XMIN_YMIN; - } else if (!strcmp (c, "xMidYMin")) { - align = SP_ASPECT_XMID_YMIN; - } else if (!strcmp (c, "xMaxYMin")) { - align = SP_ASPECT_XMAX_YMIN; - } else if (!strcmp (c, "xMinYMid")) { - align = SP_ASPECT_XMIN_YMID; - } else if (!strcmp (c, "xMidYMid")) { - align = SP_ASPECT_XMID_YMID; - } else if (!strcmp (c, "xMaxYMid")) { - align = SP_ASPECT_XMAX_YMID; - } else if (!strcmp (c, "xMinYMax")) { - align = SP_ASPECT_XMIN_YMAX; - } else if (!strcmp (c, "xMidYMax")) { - align = SP_ASPECT_XMID_YMAX; - } else if (!strcmp (c, "xMaxYMax")) { - align = SP_ASPECT_XMAX_YMAX; - } else { - break; - } - - clip = SP_ASPECT_MEET; - - while (*e && *e == 32) e += 1; - - if (*e) { - if (!strcmp (e, "meet")) { - clip = SP_ASPECT_MEET; - } else if (!strcmp (e, "slice")) { - clip = SP_ASPECT_SLICE; - } else { - break; - } - } - - this->aspect_align = align; - this->aspect_clip = clip; - } break; #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -322,7 +261,79 @@ void SPImage::set(unsigned int key, const gchar* value) { sp_image_set_curve(this); //creates a curve at the image's boundary for snapping } +// BLIP +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +void SPImage::apply_profile(Inkscape::Pixbuf *pixbuf) { + + // TODO: this will prevent using MIME data when exporting. + // Integrate color correction into loading. + pixbuf->ensurePixelFormat(Inkscape::Pixbuf::PF_GDK); + int imagewidth = pixbuf->width(); + int imageheight = pixbuf->height(); + int rowstride = pixbuf->rowstride();; + guchar* px = pixbuf->pixels(); + + if ( px ) { + DEBUG_MESSAGE( lcmsFive, "in 's sp_image_update. About to call colorprofile_get_handle()" ); + + guint profIntent = Inkscape::RENDERING_INTENT_UNKNOWN; + cmsHPROFILE prof = Inkscape::CMSSystem::getHandle( this->document, + &profIntent, + this->color_profile ); + if ( prof ) { + cmsProfileClassSignature profileClass = cmsGetDeviceClass( prof ); + if ( profileClass != cmsSigNamedColorClass ) { + int intent = INTENT_PERCEPTUAL; + + switch ( profIntent ) { + case Inkscape::RENDERING_INTENT_RELATIVE_COLORIMETRIC: + intent = INTENT_RELATIVE_COLORIMETRIC; + break; + case Inkscape::RENDERING_INTENT_SATURATION: + intent = INTENT_SATURATION; + break; + case Inkscape::RENDERING_INTENT_ABSOLUTE_COLORIMETRIC: + intent = INTENT_ABSOLUTE_COLORIMETRIC; + break; + case Inkscape::RENDERING_INTENT_PERCEPTUAL: + case Inkscape::RENDERING_INTENT_UNKNOWN: + case Inkscape::RENDERING_INTENT_AUTO: + default: + intent = INTENT_PERCEPTUAL; + } + + cmsHPROFILE destProf = cmsCreate_sRGBProfile(); + cmsHTRANSFORM transf = cmsCreateTransform( prof, + TYPE_RGBA_8, + destProf, + TYPE_RGBA_8, + intent, 0 ); + if ( transf ) { + guchar* currLine = px; + for ( int y = 0; y < imageheight; y++ ) { + // Since the types are the same size, we can do the transformation in-place + cmsDoTransform( transf, currLine, currLine, imagewidth ); + currLine += rowstride; + } + + cmsDeleteTransform( transf ); + } else { + DEBUG_MESSAGE( lcmsSix, "in 's sp_image_update. Unable to create LCMS transform." ); + } + + cmsCloseProfile( destProf ); + } else { + DEBUG_MESSAGE( lcmsSeven, "in 's sp_image_update. Profile type is named color. Can't transform." ); + } + } else { + DEBUG_MESSAGE( lcmsEight, "in 's sp_image_update. No profile found." ); + } + } +} +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + void SPImage::update(SPCtx *ctx, unsigned int flags) { + SPDocument *doc = this->document; SPItem::update(ctx, flags); @@ -339,170 +350,84 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { doc->getBase()); if (pixbuf) { -// BLIP #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - if ( this->color_profile ) - { - // TODO: this will prevent using MIME data when exporting. - // Integrate color correction into loading. - pixbuf->ensurePixelFormat(Inkscape::Pixbuf::PF_GDK); - int imagewidth = pixbuf->width(); - int imageheight = pixbuf->height(); - int rowstride = pixbuf->rowstride();; - guchar* px = pixbuf->pixels(); - - if ( px ) { - DEBUG_MESSAGE( lcmsFive, "in 's sp_image_update. About to call colorprofile_get_handle()" ); - - guint profIntent = Inkscape::RENDERING_INTENT_UNKNOWN; - cmsHPROFILE prof = Inkscape::CMSSystem::getHandle( this->document, - &profIntent, - this->color_profile ); - if ( prof ) { - cmsProfileClassSignature profileClass = cmsGetDeviceClass( prof ); - if ( profileClass != cmsSigNamedColorClass ) { - int intent = INTENT_PERCEPTUAL; - - switch ( profIntent ) { - case Inkscape::RENDERING_INTENT_RELATIVE_COLORIMETRIC: - intent = INTENT_RELATIVE_COLORIMETRIC; - break; - case Inkscape::RENDERING_INTENT_SATURATION: - intent = INTENT_SATURATION; - break; - case Inkscape::RENDERING_INTENT_ABSOLUTE_COLORIMETRIC: - intent = INTENT_ABSOLUTE_COLORIMETRIC; - break; - case Inkscape::RENDERING_INTENT_PERCEPTUAL: - case Inkscape::RENDERING_INTENT_UNKNOWN: - case Inkscape::RENDERING_INTENT_AUTO: - default: - intent = INTENT_PERCEPTUAL; - } - - cmsHPROFILE destProf = cmsCreate_sRGBProfile(); - cmsHTRANSFORM transf = cmsCreateTransform( prof, - TYPE_RGBA_8, - destProf, - TYPE_RGBA_8, - intent, 0 ); - if ( transf ) { - guchar* currLine = px; - for ( int y = 0; y < imageheight; y++ ) { - // Since the types are the same size, we can do the transformation in-place - cmsDoTransform( transf, currLine, currLine, imagewidth ); - currLine += rowstride; - } - - cmsDeleteTransform( transf ); - } else { - DEBUG_MESSAGE( lcmsSix, "in 's sp_image_update. Unable to create LCMS transform." ); - } - - cmsCloseProfile( destProf ); - } else { - DEBUG_MESSAGE( lcmsSeven, "in 's sp_image_update. Profile type is named color. Can't transform." ); - } - } else { - DEBUG_MESSAGE( lcmsEight, "in 's sp_image_update. No profile found." ); - } - } - } -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - + if ( this->color_profile ) apply_profile( pixbuf ); +#endif this->pixbuf = pixbuf; } } } + SPItemCtx *ictx = (SPItemCtx *) ctx; + + // Why continue without a pixbuf? So we can display "Missing Image" png. + // Eventually, we should properly support SVG image type (i.e. render it ourselves). + if (this->pixbuf) { - /* fixme: We are slightly violating spec here (Lauris) */ + if (!this->x._set) { + this->x.unit = SVGLength::PX; + this->x.computed = 0; + } + + if (!this->y._set) { + this->y.unit = SVGLength::PX; + this->y.computed = 0; + } + if (!this->width._set) { + this->width.unit = SVGLength::PX; this->width.computed = this->pixbuf->width(); } if (!this->height._set) { + this->height.unit = SVGLength::PX; this->height.computed = this->pixbuf->height(); } } - this->clipbox = Geom::Rect::from_xywh( - this->x.computed, this->y.computed, - this->width.computed, this->height.computed); + + // Calculate x, y, width, height from parent/initial viewport, see sp-root.cpp + if (this->x.unit == SVGLength::PERCENT) { + this->x.computed = this->x.value * ictx->viewport.width(); + } + + if (this->y.unit == SVGLength::PERCENT) { + this->y.computed = this->y.value * ictx->viewport.height(); + } + + if (this->width.unit == SVGLength::PERCENT) { + this->width.computed = this->width.value * ictx->viewport.width(); + } + + if (this->height.unit == SVGLength::PERCENT) { + this->height.computed = this->height.value * ictx->viewport.height(); + } + + // Image creates a new viewport + ictx->viewport= Geom::Rect::from_xywh( this->x.computed, this->y.computed, + this->width.computed, this->height.computed); + + this->clipbox = ictx->viewport; this->ox = this->x.computed; this->oy = this->y.computed; if (this->pixbuf) { - int pixwidth = this->pixbuf->width(); - int pixheight = this->pixbuf->height(); - - this->sx = this->width.computed / pixwidth; - this->sy = this->height.computed / pixheight; - - // preserveAspectRatio calculate bounds / clipping rectangle -- EAF - if (this->aspect_align != SP_ASPECT_NONE) { - double x, y; - - switch (this->aspect_align) { - case SP_ASPECT_XMIN_YMIN: - x = 0.0; - y = 0.0; - break; - case SP_ASPECT_XMID_YMIN: - x = 0.5; - y = 0.0; - break; - case SP_ASPECT_XMAX_YMIN: - x = 1.0; - y = 0.0; - break; - case SP_ASPECT_XMIN_YMID: - x = 0.0; - y = 0.5; - break; - case SP_ASPECT_XMID_YMID: - x = 0.5; - y = 0.5; - break; - case SP_ASPECT_XMAX_YMID: - x = 1.0; - y = 0.5; - break; - case SP_ASPECT_XMIN_YMAX: - x = 0.0; - y = 1.0; - break; - case SP_ASPECT_XMID_YMAX: - x = 0.5; - y = 1.0; - break; - case SP_ASPECT_XMAX_YMAX: - x = 1.0; - y = 1.0; - break; - default: - x = 0.0; - y = 0.0; - break; - } - if (this->aspect_clip == SP_ASPECT_SLICE) { - double scale = std::max(this->sx, this->sy); - this->sx = scale; - this->sy = scale; - } else { - double scale = std::min(this->sx, this->sy); - this->sx = scale; - this->sy = scale; - } + // Viewbox is either from SVG (not supported) or dimensions of pixbuf (PNG, JPG) + this->viewBox = Geom::Rect::from_xywh(0, 0, this->pixbuf->width(), this->pixbuf->height()); + this->viewBox_set = true; - double vw = pixwidth * this->sx; - double vh = pixheight * this->sy; - this->ox += x * (this->width.computed - vw); - this->oy += y * (this->height.computed - vh); - } + // SPItemCtx rctx = + get_rctx( ictx ); + + this->ox = c2p[4]; + this->oy = c2p[5]; + this->sx = c2p[0]; + this->sy = c2p[3]; } + + // TODO: eliminate ox, oy, sx, sy sp_image_update_canvas_image ((SPImage *) this); } -- cgit v1.2.3 From 12e03b939f58c6b6dc5495e0559fe47d7a73bb48 Mon Sep 17 00:00:00 2001 From: David Mathog Date: Sat, 22 Feb 2014 10:03:23 +0100 Subject: Fix 'preserveAspectRatio' attribute of bitmap images in EMF/WMF import/export (bug #1278645). Fixed bugs: - https://launchpad.net/bugs/1278645 (bzr r13049) --- src/sp-image.cpp | 42 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 5f630f7b7..2c20331a9 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -500,39 +500,15 @@ void SPImage::print(SPPrintContext *ctx) { int w = pb->width(); int h = pb->height(); int rs = pb->rowstride(); - //int pixskip = gdk_pixbuf_get_n_channels(pb) * gdk_pixbuf_get_bits_per_sample(pb) / 8; - int pixskip = 4; - - if (this->aspect_align == SP_ASPECT_NONE) { - Geom::Affine t; - Geom::Translate tp(this->x.computed, this->y.computed); - Geom::Scale s(this->width.computed, -this->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, this->style); - } else { // preserveAspectRatio - double vw = this->width.computed / this->sx; - double vh = this->height.computed / this->sy; - - int trimwidth = std::min(w, ceil(this->width.computed / vw * w)); - int trimheight = std::min(h, ceil(this->height.computed / vh * h)); - int trimx = std::max(0, floor((this->x.computed - this->ox) / vw * w)); - int trimy = std::max(0, floor((this->y.computed - this->oy) / vh * h)); - - double vx = std::max(this->ox, this->x.computed); - double vy = std::max(this->oy, this->y.computed); - double vcw = std::min(this->width.computed, vw); - double vch = std::min(this->height.computed, vh); - - Geom::Affine t; - Geom::Translate tp(vx, vy); - Geom::Scale s(vcw, -vch); - Geom::Translate ti(0.0, -1.0); - t = s * tp; - t = ti * t; - sp_print_image_R8G8B8A8_N(ctx, px + trimx*pixskip + trimy*rs, trimwidth, trimheight, rs, t, this->style); - } + + double vx = this->ox; + double vy = this->oy; + + Geom::Affine t; + Geom::Translate tp(vx, vy); + Geom::Scale s(this->sx, this->sy); + t = s * tp; + sp_print_image_R8G8B8A8_N(ctx, px, w, h, rs, t, this->style); delete pb; } } -- cgit v1.2.3 From d186420240c494a77ef55bfc4f725bfb85bf2b8b Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Wed, 5 Mar 2014 23:05:45 +0100 Subject: When an externally linked image is modified, mark it for update instead of directly calling update() with a bogus ctx parameter. Prevents crash and fixes LP Bug #1278571. Fixed bugs: - https://launchpad.net/bugs/1278571 (bzr r13117) --- src/sp-image.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 2c20331a9..cb8ede2b2 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -813,9 +813,7 @@ void sp_image_refresh_if_outdated( SPImage* image ) if ( !val ) { // stat call worked. Check time now if ( st.st_mtime != image->pixbuf->modificationTime() ) { - SPCtx *ctx = 0; - unsigned int flags = SP_IMAGE_HREF_MODIFIED_FLAG; - image->update(ctx, flags); + image->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG); } } } -- cgit v1.2.3