From 37eb84dcfa0f0bb84f5e62303ef7288ee922b64d Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sun, 19 Aug 2012 22:59:52 +0200 Subject: Added "virtual pad" to SPImage. (bzr r11608.1.25) --- src/sp-image.cpp | 156 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 117 insertions(+), 39 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 07885ff4d..15f565bc4 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -602,8 +602,19 @@ static void sp_image_class_init( SPImageClass * klass ) item_class->set_transform = sp_image_set_transform; } +CImage::CImage(SPImage* image) : CItem(image) { + this->spimage = image; +} + +CImage::~CImage() { +} + static void sp_image_init( SPImage *image ) { + image->cimage = new CImage(image); + image->citem = image->cimage; + image->cobject = image->cimage; + image->x.unset(); image->y.unset(); image->width.unset(); @@ -624,11 +635,10 @@ static void sp_image_init( SPImage *image ) image->lastMod = 0; } -static void sp_image_build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr ) -{ - if (((SPObjectClass *) parent_class)->build) { - ((SPObjectClass *) parent_class)->build (object, document, repr); - } +void CImage::onBuild(SPDocument *document, Inkscape::XML::Node *repr) { + SPImage* object = this->spimage; + + CItem::onBuild(document, repr); object->readAttr( "xlink:href" ); object->readAttr( "x" ); @@ -642,8 +652,14 @@ static void sp_image_build( SPObject *object, SPDocument *document, Inkscape::XM document->addResource("image", object); } -static void sp_image_release( SPObject *object ) +static void sp_image_build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr ) { + ((SPImage*)object)->cimage->onBuild(document, repr); +} + +void CImage::onRelease() { + SPImage* object = this->spimage; + SPImage *image = SP_IMAGE(object); if (object->document) { @@ -677,13 +693,18 @@ static void sp_image_release( SPObject *object ) image->curve = image->curve->unref(); } - if (((SPObjectClass *) parent_class)->release) { - ((SPObjectClass *) parent_class)->release (object); - } + CItem::onRelease(); } -static void sp_image_set( SPObject *object, unsigned int key, const gchar *value ) +static void sp_image_release( SPObject *object ) { + ((SPImage*)object)->cimage->onRelease(); + +} + +void CImage::onSet(unsigned int key, const gchar* value) { + SPImage* object = this->spimage; + SPImage *image = SP_IMAGE (object); switch (key) { @@ -796,22 +817,25 @@ static void sp_image_set( SPObject *object, unsigned int key, const gchar *value break; #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) default: - if (((SPObjectClass *) (parent_class))->set) - ((SPObjectClass *) (parent_class))->set (object, key, value); + CItem::onSet(key, value); break; } sp_image_set_curve(image); //creates a curve at the image's boundary for snapping } -static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) +static void sp_image_set( SPObject *object, unsigned int key, const gchar *value ) { + ((SPImage*)object)->cimage->onSet(key, value); +} + +void CImage::onUpdate(SPCtx *ctx, unsigned int flags) { + SPImage* object = this->spimage; + SPImage *image = SP_IMAGE(object); SPDocument *doc = object->document; - if (((SPObjectClass *) (parent_class))->update) { - ((SPObjectClass *) (parent_class))->update (object, ctx, flags); - } + CItem::onUpdate(ctx, flags); if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) { if (image->pixbuf) { @@ -1009,13 +1033,22 @@ static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) sp_image_update_canvas_image ((SPImage *) object); } -static void sp_image_modified( SPObject *object, unsigned int flags ) +static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) { + ((SPImage*)object)->cimage->onUpdate(ctx, flags); +} + +void CImage::onModified(unsigned int flags) { + SPImage* object = this->spimage; + SPImage *image = SP_IMAGE (object); - if (((SPObjectClass *) (parent_class))->modified) { - (* ((SPObjectClass *) (parent_class))->modified) (object, flags); - } + // CPPIFY: This doesn't make no sense. + // CObject::onModified is pure and CItem doesn't override this method. What was the idea behind these lines? +// if (((SPObjectClass *) (parent_class))->modified) { +// (* ((SPObjectClass *) (parent_class))->modified) (object, flags); +// } +// CItem::onModified(flags); if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = image->display; v != NULL; v = v->next) { @@ -1025,8 +1058,14 @@ static void sp_image_modified( SPObject *object, unsigned int flags ) } } -static Inkscape::XML::Node *sp_image_write( SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags ) +static void sp_image_modified( SPObject *object, unsigned int flags ) { + ((SPImage*)object)->cimage->onModified(flags); +} + +Inkscape::XML::Node *CImage::onWrite(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags ) { + SPImage* object = this->spimage; + SPImage *image = SP_IMAGE (object); if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { @@ -1056,27 +1095,37 @@ static Inkscape::XML::Node *sp_image_write( SPObject *object, Inkscape::XML::Doc } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - if (((SPObjectClass *) (parent_class))->write) { - ((SPObjectClass *) (parent_class))->write (object, xml_doc, repr, flags); - } + CItem::onWrite(xml_doc, repr, flags); return repr; } -static Geom::OptRect sp_image_bbox( SPItem const *item,Geom::Affine const &transform, SPItem::BBoxType /*type*/ ) +static Inkscape::XML::Node *sp_image_write( SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags ) { - SPImage const &image = *SP_IMAGE(item); - Geom::OptRect bbox; + return ((SPImage*)object)->cimage->onWrite(xml_doc, repr, flags); +} - if ((image.width.computed > 0.0) && (image.height.computed > 0.0)) { - bbox = Geom::Rect::from_xywh(image.x.computed, image.y.computed, image.width.computed, image.height.computed); - *bbox *= transform; - } - return bbox; +Geom::OptRect CImage::onBbox(Geom::Affine const &transform, SPItem::BBoxType type) { + SPImage* item = this->spimage; + + SPImage const &image = *SP_IMAGE(item); + Geom::OptRect bbox; + + if ((image.width.computed > 0.0) && (image.height.computed > 0.0)) { + bbox = Geom::Rect::from_xywh(image.x.computed, image.y.computed, image.width.computed, image.height.computed); + *bbox *= transform; + } + return bbox; } -static void sp_image_print( SPItem *item, SPPrintContext *ctx ) +static Geom::OptRect sp_image_bbox( SPItem const *item,Geom::Affine const &transform, SPItem::BBoxType type) { + return ((SPImage*)item)->cimage->onBbox(transform, type); +} + +void CImage::onPrint(SPPrintContext *ctx) { + SPImage* item = this->spimage; + SPImage *image = SP_IMAGE(item); if (image->pixbuf && (image->width.computed > 0.0) && (image->height.computed > 0.0) ) { @@ -1122,8 +1171,14 @@ static void sp_image_print( SPItem *item, SPPrintContext *ctx ) } } -static gchar *sp_image_description( SPItem *item ) +static void sp_image_print( SPItem *item, SPPrintContext *ctx ) { + ((SPImage*)item)->cimage->onPrint(ctx); +} + +gchar* CImage::onDescription() { + SPImage* item = this->spimage; + SPImage *image = SP_IMAGE(item); char *href_desc; if (image->href) { @@ -1145,8 +1200,14 @@ static gchar *sp_image_description( SPItem *item ) return ret; } -static Inkscape::DrawingItem *sp_image_show( SPItem *item, Inkscape::Drawing &drawing, unsigned int /*key*/, unsigned int /*flags*/ ) +static gchar *sp_image_description( SPItem *item ) { + return ((SPImage*)item)->cimage->onDescription(); +} + +Inkscape::DrawingItem* CImage::onShow(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { + SPImage* item = this->spimage; + SPImage * image = SP_IMAGE(item); Inkscape::DrawingImage *ai = new Inkscape::DrawingImage(drawing); @@ -1155,6 +1216,11 @@ static Inkscape::DrawingItem *sp_image_show( SPItem *item, Inkscape::Drawing &dr return ai; } +static Inkscape::DrawingItem *sp_image_show( SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags ) +{ + return ((SPImage*)item)->cimage->onShow(drawing, key, flags); +} + /* * utility function to try loading image from href * @@ -1279,8 +1345,9 @@ static void sp_image_update_canvas_image(SPImage *image) } } -static void sp_image_snappoints( SPItem const *item, std::vector &p, Inkscape::SnapPreferences const *snapprefs ) -{ +void CImage::onSnappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) { + SPImage* item = this->spimage; + /* 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. @@ -1310,13 +1377,19 @@ static void sp_image_snappoints( SPItem const *item, std::vector &p, Inkscape::SnapPreferences const *snapprefs ) +{ + ((SPImage*)item)->cimage->onSnappoints(p, snapprefs); +} + /* * Initially we'll do: * Transform x, y, set x, y, clear translation */ -static Geom::Affine sp_image_set_transform( SPItem *item, Geom::Affine const &xform ) -{ +Geom::Affine CImage::onSetTransform(Geom::Affine const &xform) { + SPImage* item = this->spimage; + SPImage *image = SP_IMAGE(item); /* Calculate position in parent coords. */ @@ -1355,6 +1428,11 @@ static Geom::Affine sp_image_set_transform( SPItem *item, Geom::Affine const &xf return ret; } +static Geom::Affine sp_image_set_transform( SPItem *item, Geom::Affine const &xform ) +{ + return ((SPImage*)item)->cimage->onSetTransform(xform); +} + static GdkPixbuf *sp_image_repr_read_dataURI( const gchar * uri_data ) { GdkPixbuf * pixbuf = NULL; -- cgit v1.2.3 From 370a3f5cc9e39352a081e5d5dd8c43676547a6e6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 4 Oct 2012 11:45:44 +1000 Subject: code cleanup: add own includes to cpp files or make the functions static if they are not used elsewhere. (bzr r11735) --- src/sp-image.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 07885ff4d..aa16bcdd4 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -234,7 +234,7 @@ private: PushPull(const PushPull& other); }; -void user_read_data( png_structp png_ptr, png_bytep data, png_size_t length ) +static void user_read_data( png_structp png_ptr, png_bytep data, png_size_t length ) { // g_message( "user_read_data(%d)", length ); @@ -255,12 +255,12 @@ void user_read_data( png_structp png_ptr, png_bytep data, png_size_t length ) // g_message("things out"); } -void user_write_data( png_structp /*png_ptr*/, png_bytep /*data*/, png_size_t /*length*/ ) +static void user_write_data( png_structp /*png_ptr*/, png_bytep /*data*/, png_size_t /*length*/ ) { //g_message( "user_write_data(%d)", length ); } -void user_flush_data( png_structp /*png_ptr*/ ) +static void user_flush_data( png_structp /*png_ptr*/ ) { //g_message( "user_flush_data" ); } @@ -424,7 +424,7 @@ static bool readPngAndHeaders( PushPull &youme, gint & dpiX, gint & dpiY ) return good; } -static GdkPixbuf* pixbuf_new_from_file( const char *filename, time_t &modTime, gchar*& pixPath, GError **/*error*/ ) +GdkPixbuf* pixbuf_new_from_file( const char *filename, time_t &modTime, gchar*& pixPath, GError **/*error*/ ) { GdkPixbuf* buf = NULL; PushPull youme; -- cgit v1.2.3 From 99cb30e28d4ee193f39e23464abbd7630cac8a2d Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 6 Oct 2012 23:56:27 +0200 Subject: Added virtual pad to SPFlowtext; removed old calls to virtual SPItem methods. (bzr r11608.1.46) --- src/sp-image.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 15f565bc4..3d5a9a08b 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -594,12 +594,12 @@ static void sp_image_class_init( SPImageClass * klass ) sp_object_class->modified = sp_image_modified; sp_object_class->write = sp_image_write; - item_class->bbox = sp_image_bbox; - item_class->print = sp_image_print; - item_class->description = sp_image_description; - item_class->show = sp_image_show; - item_class->snappoints = sp_image_snappoints; - item_class->set_transform = sp_image_set_transform; +// item_class->bbox = sp_image_bbox; +// item_class->print = sp_image_print; +// item_class->description = sp_image_description; +// item_class->show = sp_image_show; +// item_class->snappoints = sp_image_snappoints; +// item_class->set_transform = sp_image_set_transform; } CImage::CImage(SPImage* image) : CItem(image) { -- cgit v1.2.3 From f37e1310a960f5472325c7aac47d44c197916adb Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Tue, 20 Nov 2012 06:30:33 +0100 Subject: Fix for Bug #768149 (Incorrect Image URL can cause Loop) by Kris. (bzr r11885) --- src/sp-image.cpp | 44 ++++++++------------------------------------ 1 file changed, 8 insertions(+), 36 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index aa16bcdd4..7293c49fa 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -433,10 +433,16 @@ GdkPixbuf* pixbuf_new_from_file( const char *filename, time_t &modTime, gchar*& modTime = 0; if ( pixPath ) { g_free(pixPath); - pixPath = 0; + pixPath = NULL; + } + + struct stat stdir; + g_stat(filename, &stdir); + if (stdir.st_mode & S_IFDIR){ + //filename is not correct: it is a directory name and hence further code can not return valid results + return NULL; } - //buf = gdk_pixbuf_new_from_file( filename, error ); dump_fopen_call( filename, "pixbuf_new_from_file" ); FILE* fp = fopen_utf8name( filename, "r" ); if ( fp ) @@ -479,7 +485,6 @@ GdkPixbuf* pixbuf_new_from_file( const char *filename, time_t &modTime, gchar*& } } else if ( !latter ) { latter = TRUE; - //g_message(" READing latter"); } // Now clear out the buffer so we can read more. // (dumping out unused) @@ -492,23 +497,6 @@ GdkPixbuf* pixbuf_new_from_file( const char *filename, time_t &modTime, gchar*& buf = gdk_pixbuf_loader_get_pixbuf( loader ); if ( buf ) { g_object_ref(buf); - - if ( dpiX ) { - gchar *tmp = g_strdup_printf( "%d", dpiX ); - if ( tmp ) { - //g_message("Need to set DpiX: %s", tmp); - //gdk_pixbuf_set_option( buf, "Inkscape::DpiX", tmp ); - g_free( tmp ); - } - } - if ( dpiY ) { - gchar *tmp = g_strdup_printf( "%d", dpiY ); - if ( tmp ) { - //g_message("Need to set DpiY: %s", tmp); - //gdk_pixbuf_set_option( buf, "Inkscape::DpiY", tmp ); - g_free( tmp ); - } - } } } else { // do something @@ -525,22 +513,6 @@ GdkPixbuf* pixbuf_new_from_file( const char *filename, time_t &modTime, gchar*& g_warning ("Unable to open linked file: %s", filename); } -/* - if ( buf ) - { - const gchar* bloop = gdk_pixbuf_get_option( buf, "Inkscape::DpiX" ); - if ( bloop ) - { - g_message("DPI X is [%s]", bloop); - } - bloop = gdk_pixbuf_get_option( buf, "Inkscape::DpiY" ); - if ( bloop ) - { - g_message("DPI Y is [%s]", bloop); - } - } -*/ - return buf; } -- cgit v1.2.3 From cfe9c94712a2ff6849b123672e51b603f20e76ae Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Thu, 10 Jan 2013 23:30:09 -0800 Subject: Warning and dead code cleanup. (bzr r12014) --- src/sp-image.cpp | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 7293c49fa..7b5d56638 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -108,8 +108,6 @@ static SPItemClass *parent_class; extern "C" { void user_read_data( png_structp png_ptr, png_bytep data, png_size_t length ); - void user_write_data( png_structp png_ptr, png_bytep data, png_size_t length ); - void user_flush_data( png_structp png_ptr ); } @@ -255,16 +253,6 @@ static void user_read_data( png_structp png_ptr, png_bytep data, png_size_t leng // g_message("things out"); } -static void user_write_data( png_structp /*png_ptr*/, png_bytep /*data*/, png_size_t /*length*/ ) -{ - //g_message( "user_write_data(%d)", length ); -} - -static void user_flush_data( png_structp /*png_ptr*/ ) -{ - //g_message( "user_flush_data" ); -} - static bool readPngAndHeaders( PushPull &youme, gint & dpiX, gint & dpiY ) { -- cgit v1.2.3 From 4569747878f930a0992a2b089460f3f8cdcb39c5 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Wed, 23 Jan 2013 12:22:14 +0000 Subject: Clean up more GObject type definitions (bzr r12055) --- src/sp-image.cpp | 58 +++++++++++++++----------------------------------------- 1 file changed, 15 insertions(+), 43 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 7b5d56638..ce8879f70 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -76,9 +76,6 @@ #define MAGIC_EPSILON_TOO 1e-18 // TODO: also check if it is correct to be using two different epsilon values -static void sp_image_class_init (SPImageClass * klass); -static void sp_image_init (SPImage * image); - static void sp_image_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr); static void sp_image_release (SPObject * object); static void sp_image_set (SPObject *object, unsigned int key, const gchar *value); @@ -94,7 +91,6 @@ static Inkscape::DrawingItem *sp_image_show (SPItem *item, Inkscape::Drawing &dr static Geom::Affine sp_image_set_transform (SPItem *item, Geom::Affine const &xform); 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, Inkscape::DrawingImage *ai); @@ -102,9 +98,6 @@ 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); -static SPItemClass *parent_class; - - extern "C" { void user_read_data( png_structp png_ptr, png_bytep data, png_size_t length ); @@ -519,33 +512,12 @@ GdkPixbuf* pixbuf_new_from_file( const char *filename, GError **error ) } } -GType sp_image_get_type(void) -{ - static GType image_type = 0; - if (!image_type) { - GTypeInfo image_info = { - sizeof (SPImageClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) sp_image_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (SPImage), - 16, /* n_preallocs */ - (GInstanceInitFunc) sp_image_init, - NULL, /* value_table */ - }; - image_type = g_type_register_static (SPItem::getType (), "SPImage", &image_info, (GTypeFlags)0); - } - return image_type; -} +G_DEFINE_TYPE(SPImage, sp_image, SP_TYPE_ITEM); static void sp_image_class_init( SPImageClass * klass ) { - SPObjectClass *sp_object_class = reinterpret_cast(klass); - SPItemClass *item_class = reinterpret_cast(klass); - - parent_class = reinterpret_cast(g_type_class_ref(SPItem::getType())); + SPObjectClass *sp_object_class = SP_OBJECT_CLASS(klass); + SPItemClass *item_class = SP_ITEM_CLASS(klass); sp_object_class->build = sp_image_build; sp_object_class->release = sp_image_release; @@ -586,8 +558,8 @@ static void sp_image_init( SPImage *image ) static void sp_image_build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr ) { - if (((SPObjectClass *) parent_class)->build) { - ((SPObjectClass *) parent_class)->build (object, document, repr); + if (((SPObjectClass *) sp_image_parent_class)->build) { + ((SPObjectClass *) sp_image_parent_class)->build (object, document, repr); } object->readAttr( "xlink:href" ); @@ -637,8 +609,8 @@ static void sp_image_release( SPObject *object ) image->curve = image->curve->unref(); } - if (((SPObjectClass *) parent_class)->release) { - ((SPObjectClass *) parent_class)->release (object); + if (((SPObjectClass *) sp_image_parent_class)->release) { + ((SPObjectClass *) sp_image_parent_class)->release (object); } } @@ -756,8 +728,8 @@ static void sp_image_set( SPObject *object, unsigned int key, const gchar *value break; #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) default: - if (((SPObjectClass *) (parent_class))->set) - ((SPObjectClass *) (parent_class))->set (object, key, value); + if (((SPObjectClass *) (sp_image_parent_class))->set) + ((SPObjectClass *) (sp_image_parent_class))->set (object, key, value); break; } @@ -769,8 +741,8 @@ static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) SPImage *image = SP_IMAGE(object); SPDocument *doc = object->document; - if (((SPObjectClass *) (parent_class))->update) { - ((SPObjectClass *) (parent_class))->update (object, ctx, flags); + if (((SPObjectClass *) (sp_image_parent_class))->update) { + ((SPObjectClass *) (sp_image_parent_class))->update (object, ctx, flags); } if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) { @@ -973,8 +945,8 @@ static void sp_image_modified( SPObject *object, unsigned int flags ) { SPImage *image = SP_IMAGE (object); - if (((SPObjectClass *) (parent_class))->modified) { - (* ((SPObjectClass *) (parent_class))->modified) (object, flags); + if (((SPObjectClass *) (sp_image_parent_class))->modified) { + (* ((SPObjectClass *) (sp_image_parent_class))->modified) (object, flags); } if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { @@ -1016,8 +988,8 @@ static Inkscape::XML::Node *sp_image_write( SPObject *object, Inkscape::XML::Doc } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - if (((SPObjectClass *) (parent_class))->write) { - ((SPObjectClass *) (parent_class))->write (object, xml_doc, repr, flags); + if (((SPObjectClass *) (sp_image_parent_class))->write) { + ((SPObjectClass *) (sp_image_parent_class))->write (object, xml_doc, repr, flags); } return repr; -- cgit v1.2.3 From a0a8d020201e0e38a63d9aa3dce228d7d9e6fb35 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Thu, 14 Mar 2013 12:42:39 +0100 Subject: Various changes. (bzr r11608.1.48) --- src/sp-image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 3d5a9a08b..df2947e9a 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -587,7 +587,7 @@ static void sp_image_class_init( SPImageClass * klass ) parent_class = reinterpret_cast(g_type_class_ref(SPItem::getType())); - sp_object_class->build = sp_image_build; + //sp_object_class->build = sp_image_build; sp_object_class->release = sp_image_release; sp_object_class->set = sp_image_set; sp_object_class->update = sp_image_update; -- cgit v1.2.3 From 957c3e4b7909d42c5a13f1b1dd583f877fc32259 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 30 Mar 2013 00:46:57 +0100 Subject: Removed function pointers from SPObject and subclasses. Added some missing virtual pads for classes that were hidden by preprocessor macros. (bzr r11608.1.55) --- src/sp-image.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index df2947e9a..a219c0939 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -588,11 +588,11 @@ static void sp_image_class_init( SPImageClass * klass ) parent_class = reinterpret_cast(g_type_class_ref(SPItem::getType())); //sp_object_class->build = sp_image_build; - sp_object_class->release = sp_image_release; - sp_object_class->set = sp_image_set; - sp_object_class->update = sp_image_update; - sp_object_class->modified = sp_image_modified; - sp_object_class->write = sp_image_write; +// sp_object_class->release = sp_image_release; +// sp_object_class->set = sp_image_set; +// sp_object_class->update = sp_image_update; +// sp_object_class->modified = sp_image_modified; +// sp_object_class->write = sp_image_write; // item_class->bbox = sp_image_bbox; // item_class->print = sp_image_print; -- cgit v1.2.3 From 7df6616da5ea2debb86838366ddf746841549cdb Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 30 Mar 2013 00:56:13 +0100 Subject: Renamed virtual function names. (bzr r11608.1.57) --- src/sp-image.cpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 100263ec6..fa75915f9 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -540,10 +540,10 @@ static void sp_image_init( SPImage *image ) image->lastMod = 0; } -void CImage::onBuild(SPDocument *document, Inkscape::XML::Node *repr) { +void CImage::build(SPDocument *document, Inkscape::XML::Node *repr) { SPImage* object = this->spimage; - CItem::onBuild(document, repr); + CItem::build(document, repr); object->readAttr( "xlink:href" ); object->readAttr( "x" ); @@ -557,7 +557,7 @@ void CImage::onBuild(SPDocument *document, Inkscape::XML::Node *repr) { document->addResource("image", object); } -void CImage::onRelease() { +void CImage::release() { SPImage* object = this->spimage; SPImage *image = SP_IMAGE(object); @@ -593,10 +593,10 @@ void CImage::onRelease() { image->curve = image->curve->unref(); } - CItem::onRelease(); + CItem::release(); } -void CImage::onSet(unsigned int key, const gchar* value) { +void CImage::set(unsigned int key, const gchar* value) { SPImage* object = this->spimage; SPImage *image = SP_IMAGE (object); @@ -711,20 +711,20 @@ void CImage::onSet(unsigned int key, const gchar* value) { break; #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) default: - CItem::onSet(key, value); + CItem::set(key, value); break; } sp_image_set_curve(image); //creates a curve at the image's boundary for snapping } -void CImage::onUpdate(SPCtx *ctx, unsigned int flags) { +void CImage::update(SPCtx *ctx, unsigned int flags) { SPImage* object = this->spimage; SPImage *image = SP_IMAGE(object); SPDocument *doc = object->document; - CItem::onUpdate(ctx, flags); + CItem::update(ctx, flags); if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) { if (image->pixbuf) { @@ -922,7 +922,7 @@ void CImage::onUpdate(SPCtx *ctx, unsigned int flags) { sp_image_update_canvas_image ((SPImage *) object); } -void CImage::onModified(unsigned int flags) { +void CImage::modified(unsigned int flags) { SPImage* object = this->spimage; SPImage *image = SP_IMAGE (object); @@ -938,7 +938,7 @@ void CImage::onModified(unsigned int flags) { } -Inkscape::XML::Node *CImage::onWrite(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags ) { +Inkscape::XML::Node *CImage::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags ) { SPImage* object = this->spimage; SPImage *image = SP_IMAGE (object); @@ -970,12 +970,12 @@ Inkscape::XML::Node *CImage::onWrite(Inkscape::XML::Document *xml_doc, Inkscape: } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - CItem::onWrite(xml_doc, repr, flags); + CItem::write(xml_doc, repr, flags); return repr; } -Geom::OptRect CImage::onBbox(Geom::Affine const &transform, SPItem::BBoxType type) { +Geom::OptRect CImage::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { SPImage* item = this->spimage; SPImage const &image = *SP_IMAGE(item); @@ -988,7 +988,7 @@ Geom::OptRect CImage::onBbox(Geom::Affine const &transform, SPItem::BBoxType typ return bbox; } -void CImage::onPrint(SPPrintContext *ctx) { +void CImage::print(SPPrintContext *ctx) { SPImage* item = this->spimage; SPImage *image = SP_IMAGE(item); @@ -1036,7 +1036,7 @@ void CImage::onPrint(SPPrintContext *ctx) { } } -gchar* CImage::onDescription() { +gchar* CImage::description() { SPImage* item = this->spimage; SPImage *image = SP_IMAGE(item); @@ -1060,7 +1060,7 @@ gchar* CImage::onDescription() { return ret; } -Inkscape::DrawingItem* CImage::onShow(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { +Inkscape::DrawingItem* CImage::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { SPImage* item = this->spimage; SPImage * image = SP_IMAGE(item); @@ -1195,7 +1195,7 @@ static void sp_image_update_canvas_image(SPImage *image) } } -void CImage::onSnappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) { +void CImage::snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) { SPImage* item = this->spimage; /* An image doesn't have any nodes to snap, but still we want to be able snap one image @@ -1232,7 +1232,7 @@ void CImage::onSnappoints(std::vector &p, Inkscape * Transform x, y, set x, y, clear translation */ -Geom::Affine CImage::onSetTransform(Geom::Affine const &xform) { +Geom::Affine CImage::set_transform(Geom::Affine const &xform) { SPImage* item = this->spimage; SPImage *image = SP_IMAGE(item); @@ -1413,7 +1413,7 @@ static void sp_image_set_curve( SPImage *image ) image->curve = image->curve->unref(); } } else { - Geom::OptRect rect = image->cimage->onBbox(Geom::identity(), SPItem::VISUAL_BBOX); + Geom::OptRect rect = image->cimage->bbox(Geom::identity(), SPItem::VISUAL_BBOX); SPCurve *c = SPCurve::new_from_rect(*rect, true); if (image->curve) { @@ -1487,7 +1487,7 @@ void sp_image_refresh_if_outdated( SPImage* image ) if ( st.st_mtime != image->lastMod ) { SPCtx *ctx = 0; unsigned int flags = SP_IMAGE_HREF_MODIFIED_FLAG; - image->cimage->onUpdate(ctx, flags); + image->cimage->update(ctx, flags); } } } -- cgit v1.2.3 From a5d6e692d661f0bf7648e64e8fcb04588bb8f3ab Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Mon, 1 Apr 2013 00:07:00 +0200 Subject: Prepared exchange of casting macros. (bzr r11608.1.63) --- src/sp-image.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index fa75915f9..ab3a1ac1b 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -515,6 +515,7 @@ CImage::~CImage() { static void sp_image_init( SPImage *image ) { image->cimage = new CImage(image); + image->typeHierarchy.insert(typeid(SPImage)); delete image->citem; image->citem = image->cimage; -- cgit v1.2.3 From 69f3b6f1abb2bb422935d43262e1e99aab359954 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 2 Apr 2013 01:41:30 +0200 Subject: Added constructors to SP classes. (bzr r11608.1.67) --- src/sp-image.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index ab3a1ac1b..ecae573e6 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -499,7 +499,7 @@ GdkPixbuf* pixbuf_new_from_file( const char *filename, GError **error ) } } -G_DEFINE_TYPE(SPImage, sp_image, SP_TYPE_ITEM); +G_DEFINE_TYPE(SPImage, sp_image, G_TYPE_OBJECT); static void sp_image_class_init( SPImageClass * klass ) { @@ -512,8 +512,9 @@ CImage::CImage(SPImage* image) : CItem(image) { CImage::~CImage() { } -static void sp_image_init( SPImage *image ) -{ +SPImage::SPImage() : SPItem() { + SPImage* image = this; + image->cimage = new CImage(image); image->typeHierarchy.insert(typeid(SPImage)); @@ -521,6 +522,8 @@ static void sp_image_init( SPImage *image ) image->citem = image->cimage; image->cobject = image->cimage; + image->aspect_clip = 0; + image->x.unset(); image->y.unset(); image->width.unset(); @@ -541,6 +544,11 @@ static void sp_image_init( SPImage *image ) image->lastMod = 0; } +static void sp_image_init( SPImage *image ) +{ + new (image) SPImage(); +} + void CImage::build(SPDocument *document, Inkscape::XML::Node *repr) { SPImage* object = this->spimage; -- cgit v1.2.3 From d1af3566872dfff2aeec84859c87f1f8d13f79df Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 2 Apr 2013 19:14:36 +0200 Subject: Registered classes with new factory. Hkern, Vkern and FeFuncX have to be rewritten, as they aren't real classes. (bzr r11608.1.69) --- src/sp-image.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index ecae573e6..8cba1e87a 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -499,6 +499,17 @@ GdkPixbuf* pixbuf_new_from_file( const char *filename, GError **error ) } } + +#include "sp-factory.h" + +namespace { + SPObject* createImage() { + return new SPImage(); + } + + bool imageRegistered = SPFactory::instance().registerObject("svg:image", createImage); +} + G_DEFINE_TYPE(SPImage, sp_image, G_TYPE_OBJECT); static void sp_image_class_init( SPImageClass * klass ) -- cgit v1.2.3 From 3c213cec8c2aab1a53d0d5cb9d87659b584ac876 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Wed, 3 Apr 2013 22:47:48 +0200 Subject: Checking file presence before calling lstat (should fix Bug #785701 Inkscape freezes at opening) (bzr r12263) --- src/sp-image.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index ce8879f70..dacea3417 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -417,8 +417,12 @@ GdkPixbuf* pixbuf_new_from_file( const char *filename, time_t &modTime, gchar*& pixPath = NULL; } + //test correctness of filename + if (!g_file_test (filename, G_FILE_TEST_EXISTS)){ + return NULL; + } struct stat stdir; - g_stat(filename, &stdir); + int val = g_stat(filename, &stdir); if (stdir.st_mode & S_IFDIR){ //filename is not correct: it is a directory name and hence further code can not return valid results return NULL; @@ -429,11 +433,11 @@ GdkPixbuf* pixbuf_new_from_file( const char *filename, time_t &modTime, gchar*& if ( fp ) { { - struct stat st; - memset(&st, 0, sizeof(st)); - int val = g_stat(filename, &st); + // struct stat st; + // memset(&st, 0, sizeof(st)); + // int val = g_stat(filename, &st); if ( !val ) { - modTime = st.st_mtime; + modTime = stdir.st_mtime;//st.st_mtime; pixPath = g_strdup(filename); } } @@ -1495,7 +1499,10 @@ void sp_image_refresh_if_outdated( SPImage* image ) struct stat st; memset(&st, 0, sizeof(st)); - int val = g_stat(image->pixPath, &st); + int val = 0; + if (g_file_test (image->pixPath, G_FILE_TEST_EXISTS)){ + val = g_stat(image->pixPath, &st); + } if ( !val ) { // stat call worked. Check time now if ( st.st_mtime != image->lastMod ) { -- cgit v1.2.3 From 61003d31ea058fdf94f4f80c753c3e38426f35e4 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Fri, 5 Apr 2013 21:07:38 +0200 Subject: Merged FlowX classes. (bzr r11608.1.79) --- src/sp-image.cpp | 464 ++++++++++++++++++++++++++----------------------------- 1 file changed, 217 insertions(+), 247 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 8cba1e87a..5961bf7fa 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -510,156 +510,136 @@ namespace { bool imageRegistered = SPFactory::instance().registerObject("svg:image", createImage); } -G_DEFINE_TYPE(SPImage, sp_image, G_TYPE_OBJECT); +SPImage::SPImage() : SPItem(), CItem(this) { + delete this->citem; + this->citem = this; + this->cobject = this; -static void sp_image_class_init( SPImageClass * klass ) -{ -} - -CImage::CImage(SPImage* image) : CItem(image) { - this->spimage = image; -} - -CImage::~CImage() { -} - -SPImage::SPImage() : SPItem() { - SPImage* image = this; - - image->cimage = new CImage(image); - image->typeHierarchy.insert(typeid(SPImage)); + this->aspect_clip = 0; - delete image->citem; - image->citem = image->cimage; - image->cobject = image->cimage; + 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; - image->aspect_clip = 0; + this->curve = NULL; - image->x.unset(); - image->y.unset(); - image->width.unset(); - image->height.unset(); - image->aspect_align = SP_ASPECT_NONE; - image->clipbox = Geom::Rect(); - image->sx = image->sy = 1.0; - image->ox = image->oy = 0.0; - - image->curve = NULL; - - image->href = 0; + this->href = 0; #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - image->color_profile = 0; + this->color_profile = 0; #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - image->pixbuf = 0; - image->pixPath = 0; - image->lastMod = 0; + this->pixbuf = 0; + this->pixPath = 0; + this->lastMod = 0; } -static void sp_image_init( SPImage *image ) -{ - new (image) SPImage(); +SPImage::~SPImage() { } -void CImage::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPImage* object = this->spimage; - +void SPImage::build(SPDocument *document, Inkscape::XML::Node *repr) { CItem::build(document, repr); - object->readAttr( "xlink:href" ); - object->readAttr( "x" ); - object->readAttr( "y" ); - object->readAttr( "width" ); - object->readAttr( "height" ); - object->readAttr( "preserveAspectRatio" ); - object->readAttr( "color-profile" ); + this->readAttr( "xlink:href" ); + this->readAttr( "x" ); + this->readAttr( "y" ); + this->readAttr( "width" ); + this->readAttr( "height" ); + this->readAttr( "preserveAspectRatio" ); + this->readAttr( "color-profile" ); /* Register */ - document->addResource("image", object); + document->addResource("image", this); } -void CImage::release() { - SPImage* object = this->spimage; - - SPImage *image = SP_IMAGE(object); - - if (object->document) { +void SPImage::release() { + if (this->document) { // Unregister ourselves - object->document->removeResource("image", object); + this->document->removeResource("image", this); } - if (image->href) { - g_free (image->href); - image->href = NULL; + if (this->href) { + g_free (this->href); + this->href = NULL; } - if (image->pixbuf) { - g_object_unref (image->pixbuf); - image->pixbuf = NULL; + if (this->pixbuf) { + g_object_unref (this->pixbuf); + this->pixbuf = NULL; } #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - if (image->color_profile) { - g_free (image->color_profile); - image->color_profile = NULL; + if (this->color_profile) { + g_free (this->color_profile); + this->color_profile = NULL; } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - if (image->pixPath) { - g_free(image->pixPath); - image->pixPath = 0; + if (this->pixPath) { + g_free(this->pixPath); + this->pixPath = 0; } - if (image->curve) { - image->curve = image->curve->unref(); + if (this->curve) { + this->curve = this->curve->unref(); } CItem::release(); } -void CImage::set(unsigned int key, const gchar* value) { - SPImage* object = this->spimage; - - SPImage *image = SP_IMAGE (object); - +void SPImage::set(unsigned int key, const gchar* value) { switch (key) { case SP_ATTR_XLINK_HREF: - g_free (image->href); - image->href = (value) ? g_strdup (value) : NULL; - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG); + g_free (this->href); + this->href = (value) ? g_strdup (value) : NULL; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG); break; + case SP_ATTR_X: - if (!image->x.readAbsolute(value)) { + if (!this->x.readAbsolute(value)) { /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - image->x.unset(); + this->x.unset(); } - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_Y: - if (!image->y.readAbsolute(value)) { + if (!this->y.readAbsolute(value)) { /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - image->y.unset(); + this->y.unset(); } - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_WIDTH: - if (!image->width.readAbsolute(value)) { + if (!this->width.readAbsolute(value)) { /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - image->width.unset(); + this->width.unset(); } - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_HEIGHT: - if (!image->height.readAbsolute(value)) { + if (!this->height.readAbsolute(value)) { /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - image->height.unset(); + this->height.unset(); } - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_PRESERVEASPECTRATIO: /* Do setup before, so we can use break to escape */ - image->aspect_align = SP_ASPECT_NONE; - image->aspect_clip = SP_ASPECT_MEET; - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + this->aspect_align = SP_ASPECT_NONE; + this->aspect_clip = SP_ASPECT_MEET; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + if (value) { int len; gchar c[256]; @@ -698,8 +678,11 @@ void CImage::set(unsigned int key, const gchar* value) { } else { break; } + clip = SP_ASPECT_MEET; + while (*e && *e == 32) e += 1; + if (*e) { if (!strcmp (e, "meet")) { clip = SP_ASPECT_MEET; @@ -709,70 +692,75 @@ void CImage::set(unsigned int key, const gchar* value) { break; } } - image->aspect_align = align; - image->aspect_clip = clip; + + this->aspect_align = align; + this->aspect_clip = clip; } break; + #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) case SP_PROP_COLOR_PROFILE: - if ( image->color_profile ) { - g_free (image->color_profile); + if ( this->color_profile ) { + g_free (this->color_profile); } - image->color_profile = (value) ? g_strdup (value) : NULL; + + this->color_profile = (value) ? g_strdup (value) : NULL; #ifdef DEBUG_LCMS if ( value ) { - DEBUG_MESSAGE( lcmsFour, " color-profile set to '%s'", value ); + DEBUG_MESSAGE( lcmsFour, " color-profile set to '%s'", value ); } else { - DEBUG_MESSAGE( lcmsFour, " color-profile cleared" ); + DEBUG_MESSAGE( lcmsFour, " color-profile cleared" ); } #endif // DEBUG_LCMS // TODO check on this HREF_MODIFIED flag - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG); break; + #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) default: CItem::set(key, value); break; } - sp_image_set_curve(image); //creates a curve at the image's boundary for snapping + sp_image_set_curve(this); //creates a curve at the image's boundary for snapping } -void CImage::update(SPCtx *ctx, unsigned int flags) { - SPImage* object = this->spimage; - - SPImage *image = SP_IMAGE(object); - SPDocument *doc = object->document; +void SPImage::update(SPCtx *ctx, unsigned int flags) { + SPDocument *doc = this->document; CItem::update(ctx, flags); if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) { - if (image->pixbuf) { - g_object_unref (image->pixbuf); - image->pixbuf = NULL; + if (this->pixbuf) { + g_object_unref (this->pixbuf); + this->pixbuf = NULL; } - if ( image->pixPath ) { - g_free(image->pixPath); - image->pixPath = 0; + + if ( this->pixPath ) { + g_free(this->pixPath); + this->pixPath = 0; } - image->lastMod = 0; - if (image->href) { + + this->lastMod = 0; + + if (this->href) { GdkPixbuf *pixbuf; pixbuf = sp_image_repr_read_image ( - image->lastMod, - image->pixPath, + this->lastMod, + this->pixPath, //XML Tree being used directly while it shouldn't be. - object->getRepr()->attribute("xlink:href"), + this->getRepr()->attribute("xlink:href"), //XML Tree being used directly while it shouldn't be. - object->getRepr()->attribute("sodipodi:absref"), + this->getRepr()->attribute("sodipodi:absref"), doc->getBase()); + if (pixbuf) { pixbuf = sp_image_pixbuf_force_rgba (pixbuf); // BLIP #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - if ( image->color_profile ) + if ( this->color_profile ) { int imagewidth = gdk_pixbuf_get_width( pixbuf ); int imageheight = gdk_pixbuf_get_height( pixbuf ); @@ -784,13 +772,14 @@ void CImage::update(SPCtx *ctx, unsigned int flags) { DEBUG_MESSAGE( lcmsFive, "in 's sp_image_update. About to call colorprofile_get_handle()" ); #endif // DEBUG_LCMS guint profIntent = Inkscape::RENDERING_INTENT_UNKNOWN; - cmsHPROFILE prof = Inkscape::CMSSystem::getHandle( object->document, + cmsHPROFILE prof = Inkscape::CMSSystem::getHandle( this->document, &profIntent, - image->color_profile ); + 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; @@ -807,6 +796,7 @@ void CImage::update(SPCtx *ctx, unsigned int flags) { default: intent = INTENT_PERCEPTUAL; } + cmsHPROFILE destProf = cmsCreate_sRGBProfile(); cmsHTRANSFORM transf = cmsCreateTransform( prof, TYPE_RGBA_8, @@ -847,41 +837,42 @@ void CImage::update(SPCtx *ctx, unsigned int flags) { } } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - image->pixbuf = pixbuf; + this->pixbuf = pixbuf; // convert to premultiplied native-endian ARGB for display with Cairo - convert_pixbuf_normal_to_argb32(image->pixbuf); + convert_pixbuf_normal_to_argb32(this->pixbuf); } } } - if (image->pixbuf) { + if (this->pixbuf) { /* fixme: We are slightly violating spec here (Lauris) */ - if (!image->width._set) { - image->width.computed = gdk_pixbuf_get_width(image->pixbuf); + if (!this->width._set) { + this->width.computed = gdk_pixbuf_get_width(this->pixbuf); } - if (!image->height._set) { - image->height.computed = gdk_pixbuf_get_height(image->pixbuf); + + if (!this->height._set) { + this->height.computed = gdk_pixbuf_get_height(this->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); + Geom::Point p(this->x.computed, this->y.computed); + Geom::Point wh(this->width.computed, this->height.computed); + this->clipbox = Geom::Rect(p, p + wh); - image->ox = image->x.computed; - image->oy = image->y.computed; + this->ox = this->x.computed; + this->oy = this->y.computed; - int pixwidth = gdk_pixbuf_get_width (image->pixbuf); - int pixheight = gdk_pixbuf_get_height (image->pixbuf); + int pixwidth = gdk_pixbuf_get_width (this->pixbuf); + int pixheight = gdk_pixbuf_get_height (this->pixbuf); - image->sx = image->width.computed / pixwidth; - image->sy = image->height.computed / pixheight; + this->sx = this->width.computed / pixwidth; + this->sy = this->height.computed / pixheight; // preserveAspectRatio calculate bounds / clipping rectangle -- EAF - if (image->pixbuf && (image->aspect_align != SP_ASPECT_NONE)) { + if (this->pixbuf && (this->aspect_align != SP_ASPECT_NONE)) { double x, y; - switch (image->aspect_align) { + switch (this->aspect_align) { case SP_ASPECT_XMIN_YMIN: x = 0.0; y = 0.0; @@ -924,69 +915,65 @@ void CImage::update(SPCtx *ctx, unsigned int flags) { break; } - if (image->aspect_clip == SP_ASPECT_SLICE) { - double scale = std::max(image->sx, image->sy); - image->sx = scale; - image->sy = scale; + 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(image->sx, image->sy); - image->sx = scale; - image->sy = scale; + double scale = std::min(this->sx, this->sy); + this->sx = scale; + this->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); + double vw = pixwidth * this->sx; + double vh = pixheight * this->sy; + this->ox += x * (this->width.computed - vw); + this->oy += y * (this->height.computed - vh); } - sp_image_update_canvas_image ((SPImage *) object); + sp_image_update_canvas_image ((SPImage *) this); } -void CImage::modified(unsigned int flags) { - SPImage* object = this->spimage; - - SPImage *image = SP_IMAGE (object); - +void SPImage::modified(unsigned int flags) { // CItem::onModified(flags); if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = image->display; v != NULL; v = v->next) { + for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingImage *img = dynamic_cast(v->arenaitem); - img->setStyle(object->style); + img->setStyle(this->style); } } } -Inkscape::XML::Node *CImage::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags ) { - SPImage* object = this->spimage; - - SPImage *image = SP_IMAGE (object); - +Inkscape::XML::Node *SPImage::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags ) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:image"); } - repr->setAttribute("xlink:href", image->href); + repr->setAttribute("xlink:href", this->href); + /* fixme: Reset attribute if needed (Lauris) */ - if (image->x._set) { - sp_repr_set_svg_double(repr, "x", image->x.computed); + if (this->x._set) { + sp_repr_set_svg_double(repr, "x", this->x.computed); } - if (image->y._set) { - sp_repr_set_svg_double(repr, "y", image->y.computed); + + if (this->y._set) { + sp_repr_set_svg_double(repr, "y", this->y.computed); } - if (image->width._set) { - sp_repr_set_svg_double(repr, "width", image->width.computed); + + if (this->width._set) { + sp_repr_set_svg_double(repr, "width", this->width.computed); } - if (image->height._set) { - sp_repr_set_svg_double(repr, "height", image->height.computed); + + if (this->height._set) { + sp_repr_set_svg_double(repr, "height", this->height.computed); } //XML Tree being used directly here while it shouldn't be... - repr->setAttribute("preserveAspectRatio", object->getRepr()->attribute("preserveAspectRatio")); + repr->setAttribute("preserveAspectRatio", this->getRepr()->attribute("preserveAspectRatio")); #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - if (image->color_profile) { - repr->setAttribute("color-profile", image->color_profile); + if (this->color_profile) { + repr->setAttribute("color-profile", this->color_profile); } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -995,26 +982,20 @@ Inkscape::XML::Node *CImage::write(Inkscape::XML::Document *xml_doc, Inkscape::X return repr; } -Geom::OptRect CImage::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { - SPImage* item = this->spimage; - - SPImage const &image = *SP_IMAGE(item); +Geom::OptRect SPImage::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { Geom::OptRect bbox; - if ((image.width.computed > 0.0) && (image.height.computed > 0.0)) { - bbox = Geom::Rect::from_xywh(image.x.computed, image.y.computed, image.width.computed, image.height.computed); + if ((this->width.computed > 0.0) && (this->height.computed > 0.0)) { + bbox = Geom::Rect::from_xywh(this->x.computed, this->y.computed, this->width.computed, this->height.computed); *bbox *= transform; } + return bbox; } -void CImage::print(SPPrintContext *ctx) { - SPImage* item = this->spimage; - - SPImage *image = SP_IMAGE(item); - - if (image->pixbuf && (image->width.computed > 0.0) && (image->height.computed > 0.0) ) { - GdkPixbuf *pb = gdk_pixbuf_copy(image->pixbuf); +void SPImage::print(SPPrintContext *ctx) { + if (this->pixbuf && (this->width.computed > 0.0) && (this->height.computed > 0.0) ) { + GdkPixbuf *pb = gdk_pixbuf_copy(this->pixbuf); convert_pixbuf_argb32_to_normal(pb); guchar *px = gdk_pixbuf_get_pixels(pb); @@ -1023,27 +1004,27 @@ void CImage::print(SPPrintContext *ctx) { int rs = gdk_pixbuf_get_rowstride(pb); int pixskip = gdk_pixbuf_get_n_channels(pb) * gdk_pixbuf_get_bits_per_sample(pb) / 8; - if (image->aspect_align == SP_ASPECT_NONE) { + if (this->aspect_align == SP_ASPECT_NONE) { Geom::Affine t; - Geom::Translate tp(image->x.computed, image->y.computed); - Geom::Scale s(image->width.computed, -image->height.computed); + 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, item->style); + sp_print_image_R8G8B8A8_N(ctx, px, w, h, rs, t, this->style); } else { // preserveAspectRatio - double vw = image->width.computed / image->sx; - double vh = image->height.computed / image->sy; + double vw = this->width.computed / this->sx; + double vh = this->height.computed / this->sy; - int trimwidth = std::min(w, ceil(image->width.computed / vw * w)); - int trimheight = std::min(h, ceil(image->height.computed / vh * h)); - int trimx = std::max(0, floor((image->x.computed - image->ox) / vw * w)); - int trimy = std::max(0, floor((image->y.computed - image->oy) / vh * h)); + 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(image->ox, image->x.computed); - double vy = std::max(image->oy, image->y.computed); - double vcw = std::min(image->width.computed, vw); - double vch = std::min(image->height.computed, vh); + 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); @@ -1051,42 +1032,37 @@ void CImage::print(SPPrintContext *ctx) { 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, item->style); + sp_print_image_R8G8B8A8_N(ctx, px + trimx*pixskip + trimy*rs, trimwidth, trimheight, rs, t, this->style); } } } -gchar* CImage::description() { - SPImage* item = this->spimage; - - SPImage *image = SP_IMAGE(item); +gchar* SPImage::description() { char *href_desc; - if (image->href) { - href_desc = (strncmp(image->href, "data:", 5) == 0) + + if (this->href) { + href_desc = (strncmp(this->href, "data:", 5) == 0) ? g_strdup(_("embedded")) - : xml_quote_strdup(image->href); + : xml_quote_strdup(this->href); } else { g_warning("Attempting to call strncmp() with a null pointer."); href_desc = g_strdup("(null_pointer)"); // we call g_free() on href_desc } - char *ret = ( image->pixbuf == NULL + char *ret = ( this->pixbuf == NULL ? g_strdup_printf(_("Image with bad reference: %s"), href_desc) : g_strdup_printf(_("Image %d × %d: %s"), - gdk_pixbuf_get_width(image->pixbuf), - gdk_pixbuf_get_height(image->pixbuf), + gdk_pixbuf_get_width(this->pixbuf), + gdk_pixbuf_get_height(this->pixbuf), href_desc) ); g_free(href_desc); return ret; } -Inkscape::DrawingItem* CImage::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { - SPImage* item = this->spimage; - - SPImage * image = SP_IMAGE(item); +Inkscape::DrawingItem* SPImage::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { Inkscape::DrawingImage *ai = new Inkscape::DrawingImage(drawing); - sp_image_update_arenaitem(image, ai); + sp_image_update_arenaitem(this, ai); return ai; } @@ -1215,30 +1191,26 @@ static void sp_image_update_canvas_image(SPImage *image) } } -void CImage::snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) { - SPImage* item = this->spimage; - +void SPImage::snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) { /* 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()) { + if (this->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 //TODO Do return snappoints, but only when within visual bounding box } else { if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_IMG_CORNER)) { // 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; - Geom::Affine const i2d (item->i2dt_affine ()); + double const x0 = this->x.computed; + double const y0 = this->y.computed; + double const x1 = x0 + this->width.computed; + double const y1 = y0 + this->height.computed; + + Geom::Affine const i2d (this->i2dt_affine ()); + p.push_back(Inkscape::SnapCandidatePoint(Geom::Point(x0, y0) * i2d, Inkscape::SNAPSOURCE_IMG_CORNER, Inkscape::SNAPTARGET_IMG_CORNER)); p.push_back(Inkscape::SnapCandidatePoint(Geom::Point(x0, y1) * i2d, Inkscape::SNAPSOURCE_IMG_CORNER, Inkscape::SNAPTARGET_IMG_CORNER)); p.push_back(Inkscape::SnapCandidatePoint(Geom::Point(x1, y1) * i2d, Inkscape::SNAPSOURCE_IMG_CORNER, Inkscape::SNAPTARGET_IMG_CORNER)); @@ -1252,19 +1224,16 @@ void CImage::snappoints(std::vector &p, Inkscape:: * Transform x, y, set x, y, clear translation */ -Geom::Affine CImage::set_transform(Geom::Affine const &xform) { - SPImage* item = this->spimage; - - SPImage *image = SP_IMAGE(item); - +Geom::Affine SPImage::set_transform(Geom::Affine const &xform) { /* Calculate position in parent coords. */ - Geom::Point pos( Geom::Point(image->x.computed, image->y.computed) * xform ); + Geom::Point pos( Geom::Point(this->x.computed, this->y.computed) * xform ); /* This function takes care of translation and scaling, we return whatever parts we can't handle. */ Geom::Affine ret(Geom::Affine(xform).withoutTranslation()); Geom::Point const scale(hypot(ret[0], ret[1]), hypot(ret[2], ret[3])); + if ( scale[Geom::X] > MAGIC_EPSILON ) { ret[0] /= scale[Geom::X]; ret[1] /= scale[Geom::X]; @@ -1272,6 +1241,7 @@ Geom::Affine CImage::set_transform(Geom::Affine const &xform) { ret[0] = 1.0; ret[1] = 0.0; } + if ( scale[Geom::Y] > MAGIC_EPSILON ) { ret[2] /= scale[Geom::Y]; ret[3] /= scale[Geom::Y]; @@ -1280,15 +1250,15 @@ Geom::Affine CImage::set_transform(Geom::Affine const &xform) { ret[3] = 1.0; } - image->width = image->width.computed * scale[Geom::X]; - image->height = image->height.computed * scale[Geom::Y]; + this->width = this->width.computed * scale[Geom::X]; + this->height = this->height.computed * scale[Geom::Y]; /* Find position in item coords */ pos = pos * ret.inverse(); - image->x = pos[Geom::X]; - image->y = pos[Geom::Y]; + this->x = pos[Geom::X]; + this->y = pos[Geom::Y]; - item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); return ret; } @@ -1433,7 +1403,7 @@ static void sp_image_set_curve( SPImage *image ) image->curve = image->curve->unref(); } } else { - Geom::OptRect rect = image->cimage->bbox(Geom::identity(), SPItem::VISUAL_BBOX); + Geom::OptRect rect = image->bbox(Geom::identity(), SPItem::VISUAL_BBOX); SPCurve *c = SPCurve::new_from_rect(*rect, true); if (image->curve) { @@ -1507,7 +1477,7 @@ void sp_image_refresh_if_outdated( SPImage* image ) if ( st.st_mtime != image->lastMod ) { SPCtx *ctx = 0; unsigned int flags = SP_IMAGE_HREF_MODIFIED_FLAG; - image->cimage->update(ctx, flags); + image->update(ctx, flags); } } } -- cgit v1.2.3 From 8073924aacdda310fb7492750f78d5389b3186af Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Fri, 5 Apr 2013 22:45:01 +0200 Subject: Merged Item. (bzr r11608.1.81) --- src/sp-image.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 442d0e539..632340ee4 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -514,9 +514,7 @@ namespace { bool imageRegistered = SPFactory::instance().registerObject("svg:image", createImage); } -SPImage::SPImage() : SPItem(), CItem(this) { - delete this->citem; - this->citem = this; +SPImage::SPImage() : SPItem() { this->cobject = this; this->aspect_clip = 0; @@ -545,7 +543,7 @@ SPImage::~SPImage() { } void SPImage::build(SPDocument *document, Inkscape::XML::Node *repr) { - CItem::build(document, repr); + SPItem::build(document, repr); this->readAttr( "xlink:href" ); this->readAttr( "x" ); @@ -591,7 +589,7 @@ void SPImage::release() { this->curve = this->curve->unref(); } - CItem::release(); + SPItem::release(); } void SPImage::set(unsigned int key, const gchar* value) { @@ -722,7 +720,7 @@ void SPImage::set(unsigned int key, const gchar* value) { #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) default: - CItem::set(key, value); + SPItem::set(key, value); break; } @@ -732,7 +730,7 @@ void SPImage::set(unsigned int key, const gchar* value) { void SPImage::update(SPCtx *ctx, unsigned int flags) { SPDocument *doc = this->document; - CItem::update(ctx, flags); + SPItem::update(ctx, flags); if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) { if (this->pixbuf) { @@ -938,7 +936,7 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { } void SPImage::modified(unsigned int flags) { -// CItem::onModified(flags); +// SPItem::onModified(flags); if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { @@ -981,7 +979,7 @@ Inkscape::XML::Node *SPImage::write(Inkscape::XML::Document *xml_doc, Inkscape:: } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - CItem::write(xml_doc, repr, flags); + SPItem::write(xml_doc, repr, flags); return repr; } -- cgit v1.2.3 From 27e2102f96a5554bcd5310ec11435d155773b279 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sun, 7 Apr 2013 18:28:22 +0200 Subject: Merge Object and subclasses. Merging of SP- and C-classes complete. (bzr r11608.1.86) --- src/sp-image.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 632340ee4..d4cd2eff2 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -515,8 +515,6 @@ namespace { } SPImage::SPImage() : SPItem() { - this->cobject = this; - this->aspect_clip = 0; this->x.unset(); -- cgit v1.2.3 From ca6da31c170148cb396d4f0a023c54e202716bdd Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 11 May 2013 14:35:12 +0900 Subject: Fix for 871563 : JPG images are recompressed with lower quality when embedded (bzr r12325) --- src/sp-image.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index dacea3417..d60fbc181 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -42,6 +42,7 @@ #include "xml/quote.h" #include "xml/repr.h" #include "snap-candidate.h" +#include "preferences.h" #include "io/sys.h" #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -63,7 +64,7 @@ g_message( __VA_ARGS__ );\ } -#include "preferences.h" + #include #endif // DEBUG_LCMS #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -1469,9 +1470,12 @@ void sp_embed_image( Inkscape::XML::Node *image_node, GdkPixbuf *pb, Glib::ustri format = "png"; } + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring quality = Glib::ustring::format(prefs->getInt("/dialogs/import/quality", 100)); + gchar *data = 0; gsize length = 0; - gdk_pixbuf_save_to_buffer(pb, &data, &length, format.data(), NULL, NULL); + gdk_pixbuf_save_to_buffer(pb, &data, &length, format.data(), NULL, "quality", quality.c_str(), NULL); // Save base64 encoded data in image node // this formula taken from Glib docs -- cgit v1.2.3 From 350476a133a3965b1d7047d2f0f05bf809b177ba Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Wed, 21 Aug 2013 13:01:40 +0200 Subject: better memory leak fix (fixes bug 986271: memory leaks associated with images) Patch by David Mathog, including revert of former fix in rev 11268 (bzr r12482) --- src/sp-image.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index d60fbc181..10d294d5c 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -1056,6 +1056,7 @@ static void sp_image_print( SPItem *item, SPPrintContext *ctx ) t = ti * t; sp_print_image_R8G8B8A8_N(ctx, px + trimx*pixskip + trimy*rs, trimwidth, trimheight, rs, t, item->style); } + free(px); // else big memory leak on each image print! } } -- cgit v1.2.3 From 0697088a2e3fbb3f7777db721e8c5e4661311dbe Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 13 Sep 2013 23:14:45 +0200 Subject: Improve the functions which create GdkPixbuf from Cairo surface and vice versa. Simplifies some code. Also introduce proper refcounting into svg_preview_cache.cpp and fix its users. (bzr r12512) --- src/sp-image.cpp | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 10d294d5c..a082e2802 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -57,15 +57,13 @@ //#define DEBUG_LCMS #ifdef DEBUG_LCMS - - #define DEBUG_MESSAGE(key, ...)\ {\ g_message( __VA_ARGS__ );\ } - - #include +#else +#define DEBUG_MESSAGE(key, ...) #endif // DEBUG_LCMS #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) /* @@ -133,6 +131,8 @@ extern guint update_in_progress; gtk_widget_show_all( dialog );\ }\ } +#else // DEBUG_LCMS +#define DEBUG_MESSAGE_SCISLAC(key, ...) #endif // DEBUG_LCMS namespace Inkscape { @@ -715,23 +715,25 @@ static void sp_image_set( SPObject *object, unsigned int key, const gchar *value image->aspect_clip = clip; } break; + #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) case SP_PROP_COLOR_PROFILE: if ( image->color_profile ) { g_free (image->color_profile); } image->color_profile = (value) ? g_strdup (value) : NULL; -#ifdef DEBUG_LCMS + if ( value ) { DEBUG_MESSAGE( lcmsFour, " color-profile set to '%s'", value ); } else { DEBUG_MESSAGE( lcmsFour, " color-profile cleared" ); } -#endif // DEBUG_LCMS + // TODO check on this HREF_MODIFIED flag object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG); break; #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + default: if (((SPObjectClass *) (sp_image_parent_class))->set) ((SPObjectClass *) (sp_image_parent_class))->set (object, key, value); @@ -784,9 +786,8 @@ static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) guchar* px = gdk_pixbuf_get_pixels( pixbuf ); if ( px ) { -#ifdef DEBUG_LCMS DEBUG_MESSAGE( lcmsFive, "in 's sp_image_update. About to call colorprofile_get_handle()" ); -#endif // DEBUG_LCMS + guint profIntent = Inkscape::RENDERING_INTENT_UNKNOWN; cmsHPROFILE prof = Inkscape::CMSSystem::getHandle( object->document, &profIntent, @@ -826,34 +827,24 @@ static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) } cmsDeleteTransform( transf ); - } -#ifdef DEBUG_LCMS - else - { + } else { DEBUG_MESSAGE( lcmsSix, "in 's sp_image_update. Unable to create LCMS transform." ); } -#endif // DEBUG_LCMS + cmsCloseProfile( destProf ); - } -#ifdef DEBUG_LCMS - else - { + } else { DEBUG_MESSAGE( lcmsSeven, "in 's sp_image_update. Profile type is named color. Can't transform." ); } -#endif // DEBUG_LCMS - } -#ifdef DEBUG_LCMS - else - { + } else { DEBUG_MESSAGE( lcmsEight, "in 's sp_image_update. No profile found." ); } -#endif // DEBUG_LCMS } } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + image->pixbuf = pixbuf; - // convert to premultiplied native-endian ARGB for display with Cairo - convert_pixbuf_normal_to_argb32(image->pixbuf); + // used here for the side-effect of converting to ARGB32 + ink_cairo_surface_get_for_pixbuf(image->pixbuf); } } } @@ -1018,7 +1009,9 @@ static void sp_image_print( SPItem *item, SPPrintContext *ctx ) if (image->pixbuf && (image->width.computed > 0.0) && (image->height.computed > 0.0) ) { GdkPixbuf *pb = gdk_pixbuf_copy(image->pixbuf); - convert_pixbuf_argb32_to_normal(pb); + // GObject data is not copied, so we have to set the pixel format explicitly + g_object_set_data_full(G_OBJECT(pb), "pixel_format", g_strdup("argb32"), g_free); + ink_pixbuf_ensure_normal(pb); guchar *px = gdk_pixbuf_get_pixels(pb); int w = gdk_pixbuf_get_width(pb); @@ -1056,7 +1049,7 @@ static void sp_image_print( SPItem *item, SPPrintContext *ctx ) t = ti * t; sp_print_image_R8G8B8A8_N(ctx, px + trimx*pixskip + trimy*rs, trimwidth, trimheight, rs, t, item->style); } - free(px); // else big memory leak on each image print! + g_object_unref(pb); } } -- cgit v1.2.3 From 35dc2e5a640375d51119f2051a240454b5f5b8c8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sat, 14 Sep 2013 03:59:43 +0200 Subject: Do not recompress images when embedding and generating PDFs. Fixes blocker bug #871563. Fixed bugs: - https://launchpad.net/bugs/871563 (bzr r12516) --- src/sp-image.cpp | 566 ++++++++++++------------------------------------------- 1 file changed, 118 insertions(+), 448 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index a082e2802..724fa0ad8 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -96,12 +96,7 @@ static void sp_image_update_arenaitem (SPImage *img, Inkscape::DrawingImage *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); - -extern "C" -{ - void user_read_data( png_structp png_ptr, png_bytep data, png_size_t length ); -} - +static void pixbuf_set_mime_data(GdkPixbuf *pb, guchar *data, gsize len, GdkPixbufFormat *fmt); #ifdef DEBUG_LCMS extern guint update_in_progress; @@ -138,286 +133,15 @@ extern guint update_in_progress; namespace Inkscape { namespace IO { -class PushPull -{ -public: - gboolean first; - FILE* fp; - guchar* scratch; - gsize size; - gsize used; - gsize offset; - GdkPixbufLoader *loader; - - PushPull() : first(TRUE), - fp(0), - scratch(0), - size(0), - used(0), - offset(0), - loader(0) {}; - - gboolean readMore() - { - gboolean good = FALSE; - if ( offset ) - { - g_memmove( scratch, scratch + offset, used - offset ); - used -= offset; - offset = 0; - } - if ( used < size ) - { - gsize space = size - used; - gsize got = fread( scratch + used, 1, space, fp ); - if ( got ) - { - if ( loader ) - { - GError *err = NULL; - //g_message( " __read %d bytes", (int)got ); - if ( !gdk_pixbuf_loader_write( loader, scratch + used, got, &err ) ) - { - //g_message("_error writing pixbuf data"); - } - } - - used += got; - good = TRUE; - } - else - { - good = FALSE; - } - } - return good; - } - - gsize available() const - { - return (used - offset); - } - - gsize readOut( gpointer data, gsize length ) - { - gsize giving = available(); - if ( length < giving ) - { - giving = length; - } - g_memmove( data, scratch + offset, giving ); - offset += giving; - if ( offset >= used ) - { - offset = 0; - used = 0; - } - return giving; - } - - void clear() - { - offset = 0; - used = 0; - } - -private: - PushPull& operator = (const PushPull& other); - PushPull(const PushPull& other); -}; - -static void user_read_data( png_structp png_ptr, png_bytep data, png_size_t length ) -{ -// g_message( "user_read_data(%d)", length ); - - PushPull* youme = (PushPull*)png_get_io_ptr(png_ptr); - - gsize filled = 0; - gboolean canRead = TRUE; - - while ( filled < length && canRead ) - { - gsize some = youme->readOut( data + filled, length - filled ); - filled += some; - if ( filled < length ) - { - canRead &= youme->readMore(); - } - } -// g_message("things out"); -} - - -static bool readPngAndHeaders( PushPull &youme, gint & dpiX, gint & dpiY ) -{ - bool good = true; - - gboolean isPng = !png_sig_cmp( youme.scratch + youme.offset, 0, youme.available() ); - //g_message( " png? %s", (isPng ? "Yes":"No") ); - if ( isPng ) { - png_structp pngPtr = png_create_read_struct( PNG_LIBPNG_VER_STRING, - 0, //(png_voidp)user_error_ptr, - 0, //user_error_fn, - 0 //user_warning_fn - ); - png_infop infoPtr = pngPtr ? png_create_info_struct( pngPtr ) : 0; - - if ( pngPtr && infoPtr ) { - if ( setjmp(png_jmpbuf(pngPtr)) ) { - // libpng calls longjmp to return here if an error occurs. - good = false; - } - - if (good) { - png_set_read_fn( pngPtr, &youme, user_read_data ); - //g_message( "In" ); - - //png_read_info( pngPtr, infoPtr ); - png_read_png( pngPtr, infoPtr, PNG_TRANSFORM_IDENTITY, 0 ); - - //g_message("out"); - - /* - if ( png_get_valid( pngPtr, infoPtr, PNG_INFO_pHYs ) ) - { - g_message("pHYs chunk now valid" ); - } - if ( png_get_valid( pngPtr, infoPtr, PNG_INFO_sCAL ) ) - { - g_message("sCAL chunk now valid" ); - } - */ - - png_uint_32 res_x = 0; - png_uint_32 res_y = 0; - int unit_type = 0; - if ( png_get_pHYs( pngPtr, infoPtr, &res_x, &res_y, &unit_type) ) { -// g_message( "pHYs yes (%d, %d) %d (%s)", (int)res_x, (int)res_y, unit_type, -// (unit_type == 1? "per meter" : "unknown") -// ); - -// g_message( " dpi: (%d, %d)", -// (int)(0.5 + ((double)res_x)/39.37), -// (int)(0.5 + ((double)res_y)/39.37) ); - if ( unit_type == PNG_RESOLUTION_METER ) - { - // TODO come up with a more accurate DPI setting - dpiX = (int)(0.5 + ((double)res_x)/39.37); - dpiY = (int)(0.5 + ((double)res_y)/39.37); - } - } else { -// g_message( "pHYs no" ); - } - -/* - double width = 0; - double height = 0; - int unit = 0; - if ( png_get_sCAL(pngPtr, infoPtr, &unit, &width, &height) ) - { - gchar* vals[] = { - "unknown", // PNG_SCALE_UNKNOWN - "meter", // PNG_SCALE_METER - "radian", // PNG_SCALE_RADIAN - "last", // - NULL - }; - - g_message( "sCAL: (%f, %f) %d (%s)", - width, height, unit, - ((unit >= 0 && unit < 3) ? vals[unit]:"???") - ); - } -*/ - -#if defined(PNG_sRGB_SUPPORTED) - { - int intent = 0; - if ( png_get_sRGB(pngPtr, infoPtr, &intent) ) { -// g_message("Found an sRGB png chunk"); - } - } -#endif // defined(PNG_sRGB_SUPPORTED) - -#if defined(PNG_cHRM_SUPPORTED) - { - double white_x = 0; - double white_y = 0; - double red_x = 0; - double red_y = 0; - double green_x = 0; - double green_y = 0; - double blue_x = 0; - double blue_y = 0; - - if ( png_get_cHRM(pngPtr, infoPtr, - &white_x, &white_y, - &red_x, &red_y, - &green_x, &green_y, - &blue_x, &blue_y) ) { -// g_message("Found a cHRM png chunk"); - } - } -#endif // defined(PNG_cHRM_SUPPORTED) - -#if defined(PNG_gAMA_SUPPORTED) - { - double file_gamma = 0; - if ( png_get_gAMA(pngPtr, infoPtr, &file_gamma) ) { -// g_message("Found a gAMA png chunk"); - } - } -#endif // defined(PNG_gAMA_SUPPORTED) - -#if defined(PNG_iCCP_SUPPORTED) - { - png_charp name = 0; - int compression_type = 0; -#if (PNG_LIBPNG_VER < 10500) - png_charp profile = 0; -#else - png_bytep profile = 0; -#endif - png_uint_32 proflen = 0; - if ( png_get_iCCP(pngPtr, infoPtr, &name, &compression_type, &profile, &proflen) ) { -// g_message("Found an iCCP chunk named [%s] with %d bytes and comp %d", name, proflen, compression_type); - } - } -#endif // defined(PNG_iCCP_SUPPORTED) - - } - } else { - g_message("Error when creating PNG read struct"); - } - - // now clean it up. - if (pngPtr && infoPtr) { - png_destroy_read_struct( &pngPtr, &infoPtr, 0 ); - pngPtr = 0; - infoPtr = 0; - } else if (pngPtr) { - png_destroy_read_struct( &pngPtr, 0, 0 ); - pngPtr = 0; - } - } else { - good = false; // Was not a png file - } - - return good; -} - -GdkPixbuf* pixbuf_new_from_file( const char *filename, time_t &modTime, gchar*& pixPath, GError **/*error*/ ) +GdkPixbuf* pixbuf_new_from_file(const char *filename, time_t &modTime, gchar*& pixPath) { GdkPixbuf* buf = NULL; - PushPull youme; - gint dpiX = 0; - gint dpiY = 0; modTime = 0; if ( pixPath ) { g_free(pixPath); pixPath = NULL; } - + //test correctness of filename if (!g_file_test (filename, G_FILE_TEST_EXISTS)){ return NULL; @@ -425,95 +149,43 @@ GdkPixbuf* pixbuf_new_from_file( const char *filename, time_t &modTime, gchar*& struct stat stdir; int val = g_stat(filename, &stdir); if (stdir.st_mode & S_IFDIR){ - //filename is not correct: it is a directory name and hence further code can not return valid results + g_warning("Linked image file %s is a directory", filename); return NULL; } - dump_fopen_call( filename, "pixbuf_new_from_file" ); - FILE* fp = fopen_utf8name( filename, "r" ); - if ( fp ) - { - { - // struct stat st; - // memset(&st, 0, sizeof(st)); - // int val = g_stat(filename, &st); - if ( !val ) { - modTime = stdir.st_mtime;//st.st_mtime; - pixPath = g_strdup(filename); - } + // we need to load the entire pixbuf into memory + gchar *data = NULL; + gsize len = 0; + + if (g_file_get_contents(filename, &data, &len, NULL)) { + if (!val) { + modTime = stdir.st_mtime; + pixPath = g_strdup(filename); } GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); - if ( loader ) - { - GError *err = NULL; - - // short buffer - guchar scratch[1024]; - gboolean latter = FALSE; - - youme.fp = fp; - youme.scratch = scratch; - youme.size = sizeof(scratch); - youme.used = 0; - youme.offset = 0; - youme.loader = loader; - - while ( !feof(fp) ) - { - if ( youme.readMore() ) { - if ( youme.first ) { - //g_message( "First data chunk" ); - youme.first = FALSE; - if (readPngAndHeaders(youme, dpiX, dpiY)) - { - // TODO set the dpi to be read elsewhere - } - } else if ( !latter ) { - latter = TRUE; - } - // Now clear out the buffer so we can read more. - // (dumping out unused) - youme.clear(); - } - } - - gboolean ok = gdk_pixbuf_loader_close(loader, &err); - if ( ok ) { - buf = gdk_pixbuf_loader_get_pixbuf( loader ); - if ( buf ) { - g_object_ref(buf); - } - } else { - // do something - g_message("error loading pixbuf at close"); - } - - g_object_unref(loader); + gdk_pixbuf_loader_write(loader, (guchar *) data, len, NULL); + gdk_pixbuf_loader_close(loader, NULL); + + buf = gdk_pixbuf_loader_get_pixbuf(loader); + if (buf) { + g_object_ref(buf); + buf = sp_image_pixbuf_force_rgba(buf); + pixbuf_set_mime_data(buf, (guchar *) data, len, gdk_pixbuf_loader_get_format(loader)); } else { - g_message("error when creating pixbuf loader"); + g_free(data); + g_warning("Error loading pixbuf"); } - fclose( fp ); - fp = 0; + + // TODO: we could also read DPI, ICC profile, gamma correction, and other information + // from the file. This can be done by using format-specific libraries e.g. libpng. } else { - g_warning ("Unable to open linked file: %s", filename); + g_warning("Unable to open linked file: %s", filename); } return buf; } -GdkPixbuf* pixbuf_new_from_file( const char *filename, GError **error ) -{ - time_t modTime = 0; - gchar* pixPath = 0; - GdkPixbuf* result = pixbuf_new_from_file( filename, modTime, pixPath, error ); - if (pixPath) { - g_free(pixPath); - } - return result; -} - - } } @@ -594,6 +266,7 @@ static void sp_image_release( SPObject *object ) } if (image->pixbuf) { + g_object_set_data(G_OBJECT(image->pixbuf), "cairo_surface", NULL); g_object_unref (image->pixbuf); image->pixbuf = NULL; } @@ -775,7 +448,6 @@ static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) object->getRepr()->attribute("sodipodi:absref"), doc->getBase()); if (pixbuf) { - pixbuf = sp_image_pixbuf_force_rgba (pixbuf); // BLIP #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) if ( image->color_profile ) @@ -843,8 +515,6 @@ static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) image->pixbuf = pixbuf; - // used here for the side-effect of converting to ARGB32 - ink_cairo_surface_get_for_pixbuf(image->pixbuf); } } } @@ -1103,13 +773,14 @@ GdkPixbuf *sp_image_repr_read_image( time_t& modTime, char*& pixPath, const gcha pixPath = 0; } - const gchar *filename = href; + gchar const *filename = href; + if (filename != NULL) { if (strncmp (filename,"file:",5) == 0) { gchar *fullname = g_filename_from_uri(filename, NULL, NULL); if (fullname) { - // TODO check this. Was doing a UTF-8 to filename conversion here. - pixbuf = Inkscape::IO::pixbuf_new_from_file (fullname, modTime, pixPath, NULL); + pixbuf = Inkscape::IO::pixbuf_new_from_file(fullname, modTime, pixPath); + g_free(fullname); if (pixbuf != NULL) { return pixbuf; } @@ -1135,7 +806,7 @@ GdkPixbuf *sp_image_repr_read_image( time_t& modTime, char*& pixPath, const gcha // 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)) { - pixbuf = Inkscape::IO::pixbuf_new_from_file( fullname, modTime, pixPath, NULL ); + pixbuf = Inkscape::IO::pixbuf_new_from_file(fullname, modTime, pixPath); g_free (fullname); if (pixbuf != NULL) { return pixbuf; @@ -1145,7 +816,7 @@ GdkPixbuf *sp_image_repr_read_image( time_t& modTime, char*& pixPath, const gcha /* try filename as absolute */ if (g_file_test (filename, G_FILE_TEST_EXISTS) && !g_file_test (filename, G_FILE_TEST_IS_DIR)) { - pixbuf = Inkscape::IO::pixbuf_new_from_file( filename, modTime, pixPath, NULL ); + pixbuf = Inkscape::IO::pixbuf_new_from_file(filename, modTime, pixPath); if (pixbuf != NULL) { return pixbuf; } @@ -1163,13 +834,13 @@ GdkPixbuf *sp_image_repr_read_image( time_t& modTime, char*& pixPath, const gcha 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, modTime, pixPath, NULL ); + pixbuf = Inkscape::IO::pixbuf_new_from_file(filename, modTime, pixPath); if (pixbuf != NULL) { return pixbuf; } } /* Nope: We do not find any valid pixmap file :-( */ - pixbuf = gdk_pixbuf_new_from_xpm_data ((const gchar **) brokenimage_xpm); + pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **) brokenimage_xpm); /* It should be included xpm, so if it still does not does load, */ /* our libraries are broken */ @@ -1342,82 +1013,57 @@ static GdkPixbuf *sp_image_repr_read_dataURI( const gchar * uri_data ) return pixbuf; } -static GdkPixbuf *sp_image_repr_read_b64( const gchar * uri_data ) +static GdkPixbuf *sp_image_repr_read_b64(gchar const *uri_data) { - GdkPixbuf * pixbuf = NULL; - - static const gchar B64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - + GdkPixbuf *pixbuf = NULL; GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); - if (loader) { - bool eos = false; - bool failed = false; - const gchar* btr = uri_data; - gchar ud[4]; - guchar bd[57]; - - while (!eos) { - gint ell = 0; - for (gint j = 0; j < 19; j++) { - gint len = 0; - for (gint k = 0; k < 4; k++) { - while (isspace ((int) (*btr))) { - if ((*btr) == '\0') break; - btr++; - } - if (eos) { - ud[k] = 0; - continue; - } - if (((*btr) == '\0') || ((*btr) == '=')) { - eos = true; - ud[k] = 0; - continue; - } - ud[k] = 64; - for (gint b = 0; b < 64; b++) { /* There must a faster way to do this... ?? */ - if (B64[b] == (*btr)) { - ud[k] = (gchar) b; - break; - } - } - if (ud[k] == 64) { /* data corruption ?? */ - eos = true; - ud[k] = 0; - continue; - } - btr++; - len++; - } - guint32 bits = (guint32) ud[0]; - bits = (bits << 6) | (guint32) ud[1]; - bits = (bits << 6) | (guint32) ud[2]; - bits = (bits << 6) | (guint32) ud[3]; - bd[ell++] = (guchar) ((bits & 0xff0000) >> 16); - if (len > 2) { - bd[ell++] = (guchar) ((bits & 0xff00) >> 8); - } - if (len > 3) { - bd[ell++] = (guchar) (bits & 0xff); - } - } - if (!gdk_pixbuf_loader_write (loader, (const guchar *) bd, (size_t) ell, NULL)) { - failed = true; - break; - } - } + if (!loader) return NULL; - gdk_pixbuf_loader_close (loader, NULL); + gsize decoded_len = 0; + guchar *decoded = g_base64_decode(uri_data, &decoded_len); - if (!failed) { - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - } + if (gdk_pixbuf_loader_write(loader, decoded, decoded_len, NULL)) { + gdk_pixbuf_loader_close(loader, NULL); + pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); + g_object_ref(pixbuf); + pixbuf = sp_image_pixbuf_force_rgba(pixbuf); + pixbuf_set_mime_data(pixbuf, decoded, decoded_len, gdk_pixbuf_loader_get_format(loader)); + } else { + g_free(decoded); } + g_object_unref(loader); return pixbuf; } +// takes ownership of passed data +static void pixbuf_set_mime_data(GdkPixbuf *pb, guchar *data, gsize len, GdkPixbufFormat *fmt) +{ + cairo_surface_t *s = ink_cairo_surface_get_for_pixbuf(pb); + + gchar const *mimetype = NULL; + gchar *fmt_name = gdk_pixbuf_format_get_name(fmt); + Glib::ustring name = fmt_name; + g_free(fmt_name); + + if (name == "jpeg") { + mimetype = CAIRO_MIME_TYPE_JPEG; + } else if (name == "jpeg2000") { + mimetype = CAIRO_MIME_TYPE_JP2; + } else if (name == "png") { + mimetype = CAIRO_MIME_TYPE_PNG; + } + + if (mimetype != NULL) { + cairo_surface_set_mime_data(s, mimetype, data, len, g_free, data); + //g_message("Setting Cairo MIME data: %s", mimetype); + } else { + g_free(data); + //g_message("Not setting Cairo MIME data: unknown format %s", name.c_str()); + } +} + static void sp_image_set_curve( SPImage *image ) { //create a curve at the image's boundary for snapping @@ -1453,41 +1099,65 @@ SPCurve *sp_image_get_curve( SPImage *image ) return result; } -void sp_embed_image( Inkscape::XML::Node *image_node, GdkPixbuf *pb, Glib::ustring const &mime_in ) +void sp_embed_image(Inkscape::XML::Node *image_node, GdkPixbuf *pb) { - Glib::ustring format, mime; - if (mime_in == "image/jpeg") { - mime = mime_in; - format = "jpeg"; - } else { - mime = "image/png"; - format = "png"; + static gchar const *mimetypes[] = { + CAIRO_MIME_TYPE_JPEG, CAIRO_MIME_TYPE_JP2, CAIRO_MIME_TYPE_PNG, NULL }; + static guint mimetypes_len = g_strv_length(const_cast(mimetypes)); + + bool free_data = false; + + // check whether the pixbuf has MIME data + guchar *data = NULL; + gsize len = 0; + gchar const *data_mimetype = NULL; + + cairo_surface_t *s = reinterpret_cast(g_object_get_data(G_OBJECT(pb), "cairo_surface")); + if (s) { + for (guint i = 0; i < mimetypes_len; ++i) { + cairo_surface_get_mime_data(s, mimetypes[i], const_cast(&data), &len); + if (data != NULL) { + data_mimetype = mimetypes[i]; + break; + } + } } - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring quality = Glib::ustring::format(prefs->getInt("/dialogs/import/quality", 100)); + if (data == NULL) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring quality = Glib::ustring::format(prefs->getInt("/dialogs/import/quality", 100)); - gchar *data = 0; - gsize length = 0; - gdk_pixbuf_save_to_buffer(pb, &data, &length, format.data(), NULL, "quality", quality.c_str(), NULL); + // if there is no supported MIME data, embed as PNG + data_mimetype = "image/png"; + ink_pixbuf_ensure_normal(pb); + gdk_pixbuf_save_to_buffer(pb, reinterpret_cast(&data), &len, "png", NULL, + "quality", quality.c_str(), NULL); + free_data = true; + } // Save base64 encoded data in image node // this formula taken from Glib docs - guint needed_size = length * 4 / 3 + length * 4 / (3 * 72) + 7; - needed_size += 5 + 8 + mime.size(); // 5 bytes for data:, 8 for ;base64, + guint needed_size = len * 4 / 3 + len * 4 / (3 * 72) + 7; + needed_size += 5 + 8 + strlen(data_mimetype); // 5 bytes for data: + 8 for ;base64, - gchar *buffer = (gchar *) g_malloc(needed_size), *buf_work = buffer; - buf_work += g_sprintf(buffer, "data:%s;base64,", mime.data()); + gchar *buffer = (gchar *) g_malloc(needed_size); + gchar *buf_work = buffer; + buf_work += g_sprintf(buffer, "data:%s;base64,", data_mimetype); gint state = 0; gint save = 0; gsize written = 0; - written += g_base64_encode_step((guchar*) data, length, TRUE, buf_work, &state, &save); + written += g_base64_encode_step(data, len, TRUE, buf_work, &state, &save); written += g_base64_encode_close(TRUE, buf_work + written, &state, &save); buf_work[written] = 0; // null terminate + // TODO: this is very wasteful memory-wise. + // It would be better to only keep the binary data around, + // and base64 encode on the fly when saving the XML. image_node->setAttribute("xlink:href", buffer); + g_free(buffer); + if (free_data) g_free(data); } void sp_image_refresh_if_outdated( SPImage* image ) -- cgit v1.2.3 From e725513027a599a92254085120fa6c632882b6c9 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 14 Sep 2013 12:53:32 +0200 Subject: fix windows build (bzr r12517) --- src/sp-image.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 724fa0ad8..0e692eb40 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -1115,7 +1115,9 @@ void sp_embed_image(Inkscape::XML::Node *image_node, GdkPixbuf *pb) cairo_surface_t *s = reinterpret_cast(g_object_get_data(G_OBJECT(pb), "cairo_surface")); if (s) { for (guint i = 0; i < mimetypes_len; ++i) { - cairo_surface_get_mime_data(s, mimetypes[i], const_cast(&data), &len); + unsigned long len_long = 0; + cairo_surface_get_mime_data(s, mimetypes[i], const_cast(&data), &len_long); + len = len_long; // this assumes that the added range of long is not needed. the code below assumes gsize range of values is sufficient. if (data != NULL) { data_mimetype = mimetypes[i]; break; @@ -1137,7 +1139,7 @@ void sp_embed_image(Inkscape::XML::Node *image_node, GdkPixbuf *pb) // Save base64 encoded data in image node // this formula taken from Glib docs - guint needed_size = len * 4 / 3 + len * 4 / (3 * 72) + 7; + gsize needed_size = len * 4 / 3 + len * 4 / (3 * 72) + 7; needed_size += 5 + 8 + strlen(data_mimetype); // 5 bytes for data: + 8 for ;base64, gchar *buffer = (gchar *) g_malloc(needed_size); -- cgit v1.2.3 From 083367b313247a4cf0c082fff25e993892dc38d1 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 19 Sep 2013 02:57:10 +0200 Subject: Encapsulate the shared memory hack for Cairo and GdkPixbuf in a class called Inkscape::Pixbuf. Replace usage in the code as appropriate. (bzr r12531) --- src/sp-image.cpp | 343 ++++++++++--------------------------------------------- 1 file changed, 58 insertions(+), 285 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 0e692eb40..57bcd69b9 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -17,9 +17,6 @@ # include "config.h" #endif -// This has to be included prior to anything that includes setjmp.h, it croaks otherwise -#include - #include #include #include @@ -90,8 +87,7 @@ static Inkscape::DrawingItem *sp_image_show (SPItem *item, Inkscape::Drawing &dr static Geom::Affine sp_image_set_transform (SPItem *item, Geom::Affine const &xform); 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 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); static GdkPixbuf * sp_image_repr_read_dataURI (const gchar * uri_data); @@ -130,65 +126,6 @@ extern guint update_in_progress; #define DEBUG_MESSAGE_SCISLAC(key, ...) #endif // DEBUG_LCMS -namespace Inkscape { -namespace IO { - -GdkPixbuf* pixbuf_new_from_file(const char *filename, time_t &modTime, gchar*& pixPath) -{ - GdkPixbuf* buf = NULL; - modTime = 0; - if ( pixPath ) { - g_free(pixPath); - pixPath = NULL; - } - - //test correctness of filename - if (!g_file_test (filename, G_FILE_TEST_EXISTS)){ - return NULL; - } - struct stat stdir; - int val = g_stat(filename, &stdir); - if (stdir.st_mode & S_IFDIR){ - g_warning("Linked image file %s is a directory", filename); - return NULL; - } - - // we need to load the entire pixbuf into memory - gchar *data = NULL; - gsize len = 0; - - if (g_file_get_contents(filename, &data, &len, NULL)) { - if (!val) { - modTime = stdir.st_mtime; - pixPath = g_strdup(filename); - } - - GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); - gdk_pixbuf_loader_write(loader, (guchar *) data, len, NULL); - gdk_pixbuf_loader_close(loader, NULL); - - buf = gdk_pixbuf_loader_get_pixbuf(loader); - if (buf) { - g_object_ref(buf); - buf = sp_image_pixbuf_force_rgba(buf); - pixbuf_set_mime_data(buf, (guchar *) data, len, gdk_pixbuf_loader_get_format(loader)); - } else { - g_free(data); - g_warning("Error loading pixbuf"); - } - - // TODO: we could also read DPI, ICC profile, gamma correction, and other information - // from the file. This can be done by using format-specific libraries e.g. libpng. - } else { - g_warning("Unable to open linked file: %s", filename); - } - - return buf; -} - -} -} - G_DEFINE_TYPE(SPImage, sp_image, SP_TYPE_ITEM); static void sp_image_class_init( SPImageClass * klass ) @@ -229,8 +166,6 @@ static void sp_image_init( SPImage *image ) image->color_profile = 0; #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) image->pixbuf = 0; - image->pixPath = 0; - image->lastMod = 0; } static void sp_image_build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr ) @@ -266,8 +201,7 @@ static void sp_image_release( SPObject *object ) } if (image->pixbuf) { - g_object_set_data(G_OBJECT(image->pixbuf), "cairo_surface", NULL); - g_object_unref (image->pixbuf); + delete image->pixbuf; image->pixbuf = NULL; } @@ -278,11 +212,6 @@ static void sp_image_release( SPObject *object ) } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - if (image->pixPath) { - g_free(image->pixPath); - image->pixPath = 0; - } - if (image->curve) { image->curve = image->curve->unref(); } @@ -427,24 +356,13 @@ static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) { if (image->pixbuf) { - g_object_unref (image->pixbuf); + delete image->pixbuf; image->pixbuf = NULL; } - if ( image->pixPath ) { - g_free(image->pixPath); - image->pixPath = 0; - } - image->lastMod = 0; if (image->href) { - GdkPixbuf *pixbuf; + Inkscape::Pixbuf *pixbuf = NULL; pixbuf = sp_image_repr_read_image ( - image->lastMod, - image->pixPath, - - //XML Tree being used directly while it shouldn't be. object->getRepr()->attribute("xlink:href"), - - //XML Tree being used directly while it shouldn't be. object->getRepr()->attribute("sodipodi:absref"), doc->getBase()); if (pixbuf) { @@ -452,10 +370,13 @@ static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) if ( image->color_profile ) { - int imagewidth = gdk_pixbuf_get_width( pixbuf ); - int imageheight = gdk_pixbuf_get_height( pixbuf ); - int rowstride = gdk_pixbuf_get_rowstride( pixbuf ); - guchar* px = gdk_pixbuf_get_pixels( 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()" ); @@ -522,10 +443,10 @@ static void 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); + image->width.computed = image->pixbuf->width(); } if (!image->height._set) { - image->height.computed = gdk_pixbuf_get_height(image->pixbuf); + image->height.computed = image->pixbuf->height(); } } @@ -536,8 +457,8 @@ static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) 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); + int pixwidth = image->pixbuf->width(); + int pixheight = image->pixbuf->height(); image->sx = image->width.computed / pixwidth; image->sy = image->height.computed / pixheight; @@ -678,16 +599,15 @@ static void sp_image_print( SPItem *item, SPPrintContext *ctx ) SPImage *image = SP_IMAGE(item); if (image->pixbuf && (image->width.computed > 0.0) && (image->height.computed > 0.0) ) { - GdkPixbuf *pb = gdk_pixbuf_copy(image->pixbuf); - // GObject data is not copied, so we have to set the pixel format explicitly - g_object_set_data_full(G_OBJECT(pb), "pixel_format", g_strdup("argb32"), g_free); - ink_pixbuf_ensure_normal(pb); + Inkscape::Pixbuf *pb = new Inkscape::Pixbuf(*image->pixbuf); + pb->ensurePixelFormat(Inkscape::Pixbuf::PF_GDK); - guchar *px = gdk_pixbuf_get_pixels(pb); - int w = gdk_pixbuf_get_width(pb); - int h = gdk_pixbuf_get_height(pb); - int rs = gdk_pixbuf_get_rowstride(pb); - int pixskip = gdk_pixbuf_get_n_channels(pb) * gdk_pixbuf_get_bits_per_sample(pb) / 8; + guchar *px = pb->pixels(); + 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 (image->aspect_align == SP_ASPECT_NONE) { Geom::Affine t; @@ -739,8 +659,8 @@ static gchar *sp_image_description( SPItem *item ) char *ret = ( image->pixbuf == NULL ? g_strdup_printf(_("Image with bad reference: %s"), href_desc) : g_strdup_printf(_("Image %d × %d: %s"), - gdk_pixbuf_get_width(image->pixbuf), - gdk_pixbuf_get_height(image->pixbuf), + image->pixbuf->width(), + image->pixbuf->height(), href_desc) ); g_free(href_desc); return ret; @@ -756,22 +676,9 @@ static Inkscape::DrawingItem *sp_image_show( SPItem *item, Inkscape::Drawing &dr return ai; } -/* - * utility function to try loading image from href - * - * docbase/relative_src - * absolute_src - * - */ - -GdkPixbuf *sp_image_repr_read_image( time_t& modTime, char*& pixPath, const gchar *href, const gchar *absref, const gchar *base ) +Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base) { - GdkPixbuf *pixbuf = 0; - modTime = 0; - if ( pixPath ) { - g_free(pixPath); - pixPath = 0; - } + Inkscape::Pixbuf *inkpb = 0; gchar const *filename = href; @@ -779,18 +686,18 @@ GdkPixbuf *sp_image_repr_read_image( time_t& modTime, char*& pixPath, const gcha if (strncmp (filename,"file:",5) == 0) { gchar *fullname = g_filename_from_uri(filename, NULL, NULL); if (fullname) { - pixbuf = Inkscape::IO::pixbuf_new_from_file(fullname, modTime, pixPath); + inkpb = Inkscape::Pixbuf::create_from_file(fullname); g_free(fullname); - if (pixbuf != NULL) { - return pixbuf; + if (inkpb != NULL) { + return inkpb; } } } else if (strncmp (filename,"data:",5) == 0) { /* data URI - embedded image */ filename += 5; - pixbuf = sp_image_repr_read_dataURI (filename); - if (pixbuf != NULL) { - return pixbuf; + inkpb = Inkscape::Pixbuf::create_from_data_uri(filename); + if (inkpb != NULL) { + return inkpb; } } else { @@ -806,19 +713,19 @@ GdkPixbuf *sp_image_repr_read_image( time_t& modTime, char*& pixPath, const gcha // 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)) { - pixbuf = Inkscape::IO::pixbuf_new_from_file(fullname, modTime, pixPath); + inkpb = Inkscape::Pixbuf::create_from_file(fullname); g_free (fullname); - if (pixbuf != NULL) { - return pixbuf; + if (inkpb != NULL) { + return inkpb; } } } /* try filename as absolute */ if (g_file_test (filename, G_FILE_TEST_EXISTS) && !g_file_test (filename, G_FILE_TEST_IS_DIR)) { - pixbuf = Inkscape::IO::pixbuf_new_from_file(filename, modTime, pixPath); - if (pixbuf != NULL) { - return pixbuf; + inkpb = Inkscape::Pixbuf::create_from_file(filename); + if (inkpb != NULL) { + return inkpb; } } } @@ -834,31 +741,20 @@ GdkPixbuf *sp_image_repr_read_image( time_t& modTime, char*& pixPath, const gcha 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, modTime, pixPath); - if (pixbuf != NULL) { - return pixbuf; + inkpb = Inkscape::Pixbuf::create_from_file(filename); + if (inkpb != NULL) { + return inkpb; } } /* Nope: We do not find any valid pixmap file :-( */ - pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **) brokenimage_xpm); + 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 (pixbuf != NULL); - - return pixbuf; -} + g_assert (inkpb != NULL); -static GdkPixbuf *sp_image_pixbuf_force_rgba( GdkPixbuf * pixbuf ) -{ - GdkPixbuf* result; - if (gdk_pixbuf_get_has_alpha(pixbuf)) { - result = pixbuf; - } else { - result = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0); - g_object_unref(pixbuf); - } - return result; + return inkpb; } /* We assert that realpixbuf is either NULL or identical size to pixbuf */ @@ -866,7 +762,7 @@ static void sp_image_update_arenaitem (SPImage *image, Inkscape::DrawingImage *ai) { ai->setStyle(SP_OBJECT(image)->style); - ai->setARGB32Pixbuf(image->pixbuf); + ai->setPixbuf(image->pixbuf); ai->setOrigin(Geom::Point(image->ox, image->oy)); ai->setScale(image->sx, image->sy); ai->setClipbox(image->clipbox); @@ -957,113 +853,6 @@ static Geom::Affine sp_image_set_transform( SPItem *item, Geom::Affine const &xf return ret; } -static GdkPixbuf *sp_image_repr_read_dataURI( const gchar * uri_data ) -{ - GdkPixbuf * pixbuf = NULL; - - gint data_is_image = 0; - gint data_is_base64 = 0; - - const gchar * data = uri_data; - - while (*data) { - if (strncmp(data,"base64",6) == 0) { - /* base64-encoding */ - data_is_base64 = 1; - data_is_image = 1; // Illustrator produces embedded images without MIME type, so we assume it's image no matter what - data += 6; - } - else if (strncmp(data,"image/png",9) == 0) { - /* PNG image */ - data_is_image = 1; - data += 9; - } - else if (strncmp(data,"image/jpg",9) == 0) { - /* JPEG image */ - data_is_image = 1; - data += 9; - } - else if (strncmp(data,"image/jpeg",10) == 0) { - /* JPEG image */ - data_is_image = 1; - data += 10; - } - else { /* unrecognized option; skip it */ - while (*data) { - if (((*data) == ';') || ((*data) == ',')) { - break; - } - data++; - } - } - if ((*data) == ';') { - data++; - continue; - } - if ((*data) == ',') { - data++; - break; - } - } - - if ((*data) && data_is_image && data_is_base64) { - pixbuf = sp_image_repr_read_b64(data); - } - - return pixbuf; -} - -static GdkPixbuf *sp_image_repr_read_b64(gchar const *uri_data) -{ - GdkPixbuf *pixbuf = NULL; - GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); - - if (!loader) return NULL; - - gsize decoded_len = 0; - guchar *decoded = g_base64_decode(uri_data, &decoded_len); - - if (gdk_pixbuf_loader_write(loader, decoded, decoded_len, NULL)) { - gdk_pixbuf_loader_close(loader, NULL); - pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); - g_object_ref(pixbuf); - pixbuf = sp_image_pixbuf_force_rgba(pixbuf); - pixbuf_set_mime_data(pixbuf, decoded, decoded_len, gdk_pixbuf_loader_get_format(loader)); - } else { - g_free(decoded); - } - g_object_unref(loader); - - return pixbuf; -} - -// takes ownership of passed data -static void pixbuf_set_mime_data(GdkPixbuf *pb, guchar *data, gsize len, GdkPixbufFormat *fmt) -{ - cairo_surface_t *s = ink_cairo_surface_get_for_pixbuf(pb); - - gchar const *mimetype = NULL; - gchar *fmt_name = gdk_pixbuf_format_get_name(fmt); - Glib::ustring name = fmt_name; - g_free(fmt_name); - - if (name == "jpeg") { - mimetype = CAIRO_MIME_TYPE_JPEG; - } else if (name == "jpeg2000") { - mimetype = CAIRO_MIME_TYPE_JP2; - } else if (name == "png") { - mimetype = CAIRO_MIME_TYPE_PNG; - } - - if (mimetype != NULL) { - cairo_surface_set_mime_data(s, mimetype, data, len, g_free, data); - //g_message("Setting Cairo MIME data: %s", mimetype); - } else { - g_free(data); - //g_message("Not setting Cairo MIME data: unknown format %s", name.c_str()); - } -} - static void sp_image_set_curve( SPImage *image ) { //create a curve at the image's boundary for snapping @@ -1099,31 +888,16 @@ SPCurve *sp_image_get_curve( SPImage *image ) return result; } -void sp_embed_image(Inkscape::XML::Node *image_node, GdkPixbuf *pb) +void sp_embed_image(Inkscape::XML::Node *image_node, Inkscape::Pixbuf *pb) { - static gchar const *mimetypes[] = { - CAIRO_MIME_TYPE_JPEG, CAIRO_MIME_TYPE_JP2, CAIRO_MIME_TYPE_PNG, NULL }; - static guint mimetypes_len = g_strv_length(const_cast(mimetypes)); - bool free_data = false; // check whether the pixbuf has MIME data guchar *data = NULL; gsize len = 0; - gchar const *data_mimetype = NULL; - - cairo_surface_t *s = reinterpret_cast(g_object_get_data(G_OBJECT(pb), "cairo_surface")); - if (s) { - for (guint i = 0; i < mimetypes_len; ++i) { - unsigned long len_long = 0; - cairo_surface_get_mime_data(s, mimetypes[i], const_cast(&data), &len_long); - len = len_long; // this assumes that the added range of long is not needed. the code below assumes gsize range of values is sufficient. - if (data != NULL) { - data_mimetype = mimetypes[i]; - break; - } - } - } + std::string data_mimetype; + + data = const_cast(pb->getMimeData(len, data_mimetype)); if (data == NULL) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1131,8 +905,7 @@ void sp_embed_image(Inkscape::XML::Node *image_node, GdkPixbuf *pb) // if there is no supported MIME data, embed as PNG data_mimetype = "image/png"; - ink_pixbuf_ensure_normal(pb); - gdk_pixbuf_save_to_buffer(pb, reinterpret_cast(&data), &len, "png", NULL, + gdk_pixbuf_save_to_buffer(pb->getPixbufRaw(), reinterpret_cast(&data), &len, "png", NULL, "quality", quality.c_str(), NULL); free_data = true; } @@ -1140,11 +913,11 @@ void sp_embed_image(Inkscape::XML::Node *image_node, GdkPixbuf *pb) // Save base64 encoded data in image node // this formula taken from Glib docs gsize needed_size = len * 4 / 3 + len * 4 / (3 * 72) + 7; - needed_size += 5 + 8 + strlen(data_mimetype); // 5 bytes for data: + 8 for ;base64, + needed_size += 5 + 8 + data_mimetype.size(); // 5 bytes for data: + 8 for ;base64, gchar *buffer = (gchar *) g_malloc(needed_size); gchar *buf_work = buffer; - buf_work += g_sprintf(buffer, "data:%s;base64,", data_mimetype); + buf_work += g_sprintf(buffer, "data:%s;base64,", data_mimetype.c_str()); gint state = 0; gint save = 0; @@ -1164,18 +937,18 @@ void sp_embed_image(Inkscape::XML::Node *image_node, GdkPixbuf *pb) void sp_image_refresh_if_outdated( SPImage* image ) { - if ( image->href && image->lastMod ) { + if ( image->href && image->pixbuf && image->pixbuf->modificationTime()) { // It *might* change struct stat st; memset(&st, 0, sizeof(st)); int val = 0; - if (g_file_test (image->pixPath, G_FILE_TEST_EXISTS)){ - val = g_stat(image->pixPath, &st); + if (g_file_test (image->pixbuf->originalPath().c_str(), G_FILE_TEST_EXISTS)){ + val = g_stat(image->pixbuf->originalPath().c_str(), &st); } if ( !val ) { // stat call worked. Check time now - if ( st.st_mtime != image->lastMod ) { + if ( st.st_mtime != image->pixbuf->modificationTime() ) { SPCtx *ctx = 0; unsigned int flags = SP_IMAGE_HREF_MODIFIED_FLAG; sp_image_update(image, ctx, flags); -- cgit v1.2.3 From b8e959420c0a1f34995b5186adf1f4bf4ac30858 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 19 Sep 2013 17:52:49 +0200 Subject: Remove a warning when embedding an image with a mimetype which is not directly handled by Cairo (bzr r12542) --- src/sp-image.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index b4125d01b..47d8287b4 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -863,13 +863,9 @@ void sp_embed_image(Inkscape::XML::Node *image_node, Inkscape::Pixbuf *pb) data = const_cast(pb->getMimeData(len, data_mimetype)); if (data == NULL) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring quality = Glib::ustring::format(prefs->getInt("/dialogs/import/quality", 100)); - // if there is no supported MIME data, embed as PNG data_mimetype = "image/png"; - gdk_pixbuf_save_to_buffer(pb->getPixbufRaw(), reinterpret_cast(&data), &len, "png", NULL, - "quality", quality.c_str(), NULL); + gdk_pixbuf_save_to_buffer(pb->getPixbufRaw(), reinterpret_cast(&data), &len, "png", NULL, NULL); free_data = true; } -- cgit v1.2.3 From 10ad175dc0513e396f3fcd57917537b6708ab515 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 19 Sep 2013 17:56:58 +0200 Subject: Fix serious potential bug in SPImage::print (bzr r12543) --- src/sp-image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 47d8287b4..80daf33c3 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -609,7 +609,7 @@ void SPImage::print(SPPrintContext *ctx) { t = ti * t; sp_print_image_R8G8B8A8_N(ctx, px + trimx*pixskip + trimy*rs, trimwidth, trimheight, rs, t, this->style); } - g_object_unref(pb); + delete pb; } } -- cgit v1.2.3 From eb3598e7e27619c759ef33bb9ec4ffb8898523de Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 20 Sep 2013 00:45:16 -0400 Subject: Refactor status-bar text for multiple items, was very broken Fixed bugs: - https://launchpad.net/bugs/1199192 (bzr r12550) --- src/sp-image.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 80daf33c3..c3352fcf0 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -613,6 +613,10 @@ void SPImage::print(SPPrintContext *ctx) { } } +const char* SPImage::display_name() { + return _("Image"); +} + gchar* SPImage::description() { char *href_desc; @@ -626,8 +630,8 @@ gchar* SPImage::description() { } char *ret = ( this->pixbuf == NULL - ? g_strdup_printf(_("Image with bad reference: %s"), href_desc) - : g_strdup_printf(_("Image %d × %d: %s"), + ? g_strdup_printf(_("[bad reference]: %s"), href_desc) + : g_strdup_printf(_("%d × %d: %s"), this->pixbuf->width(), this->pixbuf->height(), href_desc) ); -- cgit v1.2.3 From 4768c87314c3de876a7bffa4006cd43aa57dac74 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 21 Sep 2013 13:02:20 +0100 Subject: Drop unused static function declarations (bzr r12565) --- src/sp-image.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index c3352fcf0..38c749dd3 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -78,9 +78,6 @@ 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); -static GdkPixbuf * sp_image_repr_read_dataURI (const gchar * uri_data); -static GdkPixbuf * sp_image_repr_read_b64 (const gchar * uri_data); -static void pixbuf_set_mime_data(GdkPixbuf *pb, guchar *data, gsize len, GdkPixbufFormat *fmt); #ifdef DEBUG_LCMS extern guint update_in_progress; -- cgit v1.2.3 From 6f65ca557f8ad953b55b9a703643bbc790eb8da5 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 24 Sep 2013 11:09:43 -0400 Subject: change names for displayName and detailedDescription, improve char code and remove const. (bzr r12584) --- src/sp-image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 38c749dd3..05dfb5f48 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -610,7 +610,7 @@ void SPImage::print(SPPrintContext *ctx) { } } -const char* SPImage::display_name() { +const char* SPImage::displayName() { return _("Image"); } -- cgit v1.2.3 From bdcd0645191270e9136557237f7c48ca5944fc73 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 15:49:01 -0300 Subject: fix one code path where fullname wasn't freed (bzr r12614) --- src/sp-image.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 05dfb5f48..f2fc6a37a 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -682,11 +682,12 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre // 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); - g_free (fullname); if (inkpb != NULL) { + g_free (fullname); return inkpb; } } + g_free (fullname); } /* try filename as absolute */ -- cgit v1.2.3 From 03eb26c89db28d9d3a6568c1141046f734715b62 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Thu, 3 Oct 2013 20:50:06 -0300 Subject: if this->pixbuf check must come earlier to prevent crash (bzr r12653) --- src/sp-image.cpp | 132 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 67 insertions(+), 65 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index f2fc6a37a..86668d9ed 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -433,73 +433,75 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { this->ox = this->x.computed; this->oy = this->y.computed; - 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->pixbuf && (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->pixbuf) { + int pixwidth = this->pixbuf->width(); + int pixheight = this->pixbuf->height(); - 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; - } + 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; - double vw = pixwidth * this->sx; - double vh = pixheight * this->sy; - this->ox += x * (this->width.computed - vw); - this->oy += y * (this->height.computed - vh); + 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; + } + + double vw = pixwidth * this->sx; + double vh = pixheight * this->sy; + this->ox += x * (this->width.computed - vw); + this->oy += y * (this->height.computed - vh); + } } sp_image_update_canvas_image ((SPImage *) this); } -- cgit v1.2.3 From 73edade30f70b4c0ad94c9561b4e4ec0675465b0 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sun, 27 Oct 2013 00:00:51 +0200 Subject: Added some consts. (bzr r12729) --- src/sp-image.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 86668d9ed..1032b6d93 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -555,7 +555,7 @@ Inkscape::XML::Node *SPImage::write(Inkscape::XML::Document *xml_doc, Inkscape:: return repr; } -Geom::OptRect SPImage::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { +Geom::OptRect SPImage::bbox(Geom::Affine const &transform, SPItem::BBoxType type) const { Geom::OptRect bbox; if ((this->width.computed > 0.0) && (this->height.computed > 0.0)) { @@ -612,11 +612,11 @@ void SPImage::print(SPPrintContext *ctx) { } } -const char* SPImage::displayName() { +const char* SPImage::displayName() const { return _("Image"); } -gchar* SPImage::description() { +gchar* SPImage::description() const { char *href_desc; if (this->href) { @@ -748,7 +748,7 @@ static void sp_image_update_canvas_image(SPImage *image) } } -void SPImage::snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) { +void SPImage::snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const { /* 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. -- cgit v1.2.3 From 4aa096a5a8537b6e28c4502d817e546b8b7fdd9b Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Sun, 27 Oct 2013 20:57:50 +0100 Subject: "fix" some "unused parameter" warnings (bzr r12736) --- src/sp-image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/sp-image.cpp') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 1032b6d93..8f7a60ca6 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -555,7 +555,7 @@ Inkscape::XML::Node *SPImage::write(Inkscape::XML::Document *xml_doc, Inkscape:: return repr; } -Geom::OptRect SPImage::bbox(Geom::Affine const &transform, SPItem::BBoxType type) const { +Geom::OptRect SPImage::bbox(Geom::Affine const &transform, SPItem::BBoxType /*type*/) const { Geom::OptRect bbox; if ((this->width.computed > 0.0) && (this->height.computed > 0.0)) { @@ -638,7 +638,7 @@ gchar* SPImage::description() const { return ret; } -Inkscape::DrawingItem* SPImage::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { +Inkscape::DrawingItem* SPImage::show(Inkscape::Drawing &drawing, unsigned int /*key*/, unsigned int /*flags*/) { Inkscape::DrawingImage *ai = new Inkscape::DrawingImage(drawing); sp_image_update_arenaitem(this, ai); -- cgit v1.2.3 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