void URIReference::attach(const URI &uri) throw(BadURIException) { SPDocument *document = NULL; // Attempt to get the document that contains the URI if (_owner) { document = _owner->document; } else if (_owner_document) { document = _owner_document; } // createChildDoc() assumes that the referenced file is an SVG. // PNG and JPG files are allowed (in the case of feImage). gchar *filename = uri.toString(); bool skip = false; if( g_str_has_suffix( filename, ".jpg" ) || g_str_has_suffix( filename, ".JPG" ) || g_str_has_suffix( filename, ".png" ) || g_str_has_suffix( filename, ".PNG" ) ) { skip = true; } // The path contains references to separate document files to load. if(document && uri.getPath() && !skip ) { std::string base = document->getBase() ? document->getBase() : ""; std::string path = uri.getFullPath(base); if(!path.empty()) { document = document->createChildDoc(path); } else { document = NULL; } } if(!document) { g_warning("Can't get document for referenced URI: %s", filename); g_free( filename ); return; } g_free( filename ); gchar const *fragment = uri.getFragment(); if ( !uri.isRelative() || uri.getQuery() || !fragment ) { throw UnsupportedURIException(); } /* FIXME !!! real xpointer support should be delegated to document */ /* for now this handles the minimal xpointer form that SVG 1.0 * requires of us */ gchar *id = NULL; if (!strncmp(fragment, "xpointer(", 9)) { /* FIXME !!! this is wasteful */ /* FIXME: It looks as though this is including "))" in the id. I suggest moving the strlen calculation and validity testing to before strdup, and copying just the id without the "))". -- pjrm */ if (!strncmp(fragment, "xpointer(id(", 12)) { id = g_strdup(fragment+12); size_t const len = strlen(id); if ( len < 3 || strcmp(id+len-2, "))") ) { g_free(id); throw MalformedURIException(); } } else { throw UnsupportedURIException(); } } else { id = g_strdup(fragment); } /* FIXME !!! validate id as an NCName somewhere */ _connection.disconnect(); delete _uri; _uri = new URI(uri); _setObject(document->getObjectById(id)); _connection = document->connectIdChanged(id, sigc::mem_fun(*this, &URIReference::_setObject)); g_free(id); }
void SPImage::update(SPCtx *ctx, unsigned int flags) { SPDocument *doc = this->document; SPItem::update(ctx, flags); if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) { delete this->pixbuf; this->pixbuf = NULL; if (this->href) { Inkscape::Pixbuf *pixbuf = NULL; pixbuf = sp_image_repr_read_image ( this->getRepr()->attribute("xlink:href"), this->getRepr()->attribute("sodipodi:absref"), doc->getBase()); if (pixbuf) { #if 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) { 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(); } } // 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) { // 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; // 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); }