sp-image.cpp revision 4bf96339af907a30f499f5fa08790abe0b3c5926
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * SVG <image> implementation
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Lauris Kaplinski <lauris@kaplinski.com>
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Edward Flick (EAF)
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen * Abhishek Sharma
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Jon A. Cruz <jon@joncruz.org>
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Copyright (C) 1999-2005 Authors
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Copyright (C) 2000-2001 Ximian, Inc.
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Released under GNU GPL, read the file 'COPYING' for more information
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free//Added for preserveAspectRatio support -- EAF
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#include "brokenimage.xpm"
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#endif // HAVE_LIBLCMS2
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free//#define DEBUG_LCMS
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#endif // DEBUG_LCMS
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free// TODO: give these constants better names:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free// TODO: also check if it is correct to be using two different epsilon values
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freestatic void sp_image_set_curve(SPImage *image);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freestatic Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base );
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freestatic void sp_image_update_arenaitem (SPImage *img, Inkscape::DrawingImage *ai);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freestatic void sp_image_update_canvas_image (SPImage *image);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free Inkscape::Preferences *prefs = Inkscape::Preferences::get();\
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free bool dump = prefs->getBool("/options/scislac/" #key);\
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen bool dumpD = prefs->getBool("/options/scislac/" #key "D");\
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free bool dumpD2 = prefs->getBool("/options/scislac/" #key "D2");\
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen dumpD &&= ( (update_in_progress == 0) || dumpD2 );\
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen GtkWidget *dialog = gtk_message_dialog_new(NULL,\
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen g_signal_connect_swapped(dialog, "response",\
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen#else // DEBUG_LCMS
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#endif // DEBUG_LCMS
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freevoid SPImage::build(SPDocument *document, Inkscape::XML::Node *repr) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Register */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free // Unregister ourselves
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->document->removeResource("image", this);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free delete this->pixbuf;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freevoid SPImage::set(unsigned int key, const gchar* value) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->href = (value) ? g_strdup (value) : NULL;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* ex, em not handled correctly. */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* ex, em not handled correctly. */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* ex, em not handled correctly. */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* ex, em not handled correctly. */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->color_profile = (value) ? g_strdup (value) : NULL;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free DEBUG_MESSAGE( lcmsFour, "<this> color-profile set to '%s'", value );
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free DEBUG_MESSAGE( lcmsFour, "<this> color-profile cleared" );
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free // TODO check on this HREF_MODIFIED flag
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free sp_image_set_curve(this); //creates a curve at the image's boundary for snapping
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freevoid SPImage::apply_profile(Inkscape::Pixbuf *pixbuf) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free // TODO: this will prevent using MIME data when exporting.
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free // Integrate color correction into loading.
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free pixbuf->ensurePixelFormat(Inkscape::Pixbuf::PF_GDK);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free DEBUG_MESSAGE( lcmsFive, "in <image>'s sp_image_update. About to call colorprofile_get_handle()" );
this->color_profile );
if ( prof ) {
switch ( profIntent ) {
intent, 0 );
if ( transf ) {
for ( int y = 0; y < imageheight; y++ ) {
DEBUG_MESSAGE( lcmsSeven, "in <image>'s sp_image_update. Profile type is named color. Can't transform." );
delete this->pixbuf;
if (this->href) {
if (pixbuf) {
if (this->pixbuf) {
if (!this->x._set) {
this->x.computed = 0;
if (!this->y._set) {
this->y.computed = 0;
// Calculate x, y, width, height from parent/initial viewport, see sp-root.cpp
if (this->pixbuf) {
this->viewBox_set = true;
Inkscape::XML::Node *SPImage::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags ) {
if (this->x._set) {
if (this->y._set) {
if (this->color_profile) {
return repr;
bbox = Geom::Rect::from_xywh(this->x.computed, this->y.computed, this->width.computed, this->height.computed);
return bbox;
t = s * tp;
delete pb;
char *href_desc;
if (this->href) {
href_desc) );
return ret;
Inkscape::DrawingItem* SPImage::show(Inkscape::Drawing &drawing, unsigned int /*key*/, unsigned int /*flags*/) {
return ai;
Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base)
if (fullname) {
return inkpb;
return inkpb;
if (!docbase) {
return inkpb;
return inkpb;
g_warning ("<image xlink:href=\"%s\"> did not resolve to a valid image file (base dir is %s), now trying sodipodi:absref=\"%s\"", href, base, absref);
g_warning ("xlink:href did not resolve to a valid image file, now trying sodipodi:absref=\"%s\"", absref);
return inkpb;
return inkpb;
void SPImage::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) const {
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));
p.push_back(Inkscape::SnapCandidatePoint(Geom::Point(x1, y0) * i2d, Inkscape::SNAPSOURCE_IMG_CORNER, Inkscape::SNAPTARGET_IMG_CORNER));
return ret;
if ((image->height.computed < MAGIC_EPSILON_TOO) || (image->width.computed < MAGIC_EPSILON_TOO) || (image->clip_ref->getObject())) {
c->unref();
return result;
bool free_data = false;
gdk_pixbuf_save_to_buffer(pb->getPixbufRaw(), reinterpret_cast<gchar**>(&data), &len, "png", NULL, NULL);
free_data = true;
int val = 0;
if ( !val ) {