summaryrefslogtreecommitdiffstats
path: root/src/object
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2018-05-13 14:35:04 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2018-05-13 14:35:04 +0000
commite6616e3a2aa1ffa83fe173e2180849d1ca14a49d (patch)
treee7b2d1392abea351244452fba0356d72509b900f /src/object
parentAdd preview for numeric OpenType features. (diff)
downloadinkscape-e6616e3a2aa1ffa83fe173e2180849d1ca14a49d.tar.gz
inkscape-e6616e3a2aa1ffa83fe173e2180849d1ca14a49d.zip
Fix bug embeding SVG as PNG
Diffstat (limited to 'src/object')
-rw-r--r--src/object/sp-image.cpp95
-rw-r--r--src/object/sp-image.h2
2 files changed, 73 insertions, 24 deletions
diff --git a/src/object/sp-image.cpp b/src/object/sp-image.cpp
index 3a76b9633..cc319a924 100644
--- a/src/object/sp-image.cpp
+++ b/src/object/sp-image.cpp
@@ -125,7 +125,6 @@ SPImage::SPImage() : SPItem(), SPViewBox() {
this->color_profile = 0;
#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
this->pixbuf = 0;
- this->on_construct = true;
}
SPImage::~SPImage() {
@@ -327,12 +326,9 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) {
SPDocument *doc = this->document;
SPItem::update(ctx, flags);
-
- if ((flags & SP_IMAGE_HREF_MODIFIED_FLAG) || this->on_construct) {
- this->on_construct = false;
+ 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 (
@@ -512,24 +508,23 @@ gchar* SPImage::description() const {
this->pixbuf->height(),
href_desc) );
-// if (this->pixbuf == NULL &&
-// this->document)
-// {
-// Inkscape::Pixbuf * pb = NULL;
-// pb = sp_image_repr_read_image (
-// this->getRepr()->attribute("xlink:href"),
-// this->getRepr()->attribute("sodipodi:absref"),
-// this->document->getBase());
-
-// if (pb) {
-// ret = ( pb == NULL ? g_strdup_printf(_("[bad reference]: %s"), href_desc)
-// : g_strdup_printf(_("%d &#215; %d: %s"),
-// pb->width(),
-// pb->height(),
-// href_desc));
-// delete pb;
-// }
-// }
+ if (this->pixbuf == NULL &&
+ this->document)
+ {
+ Inkscape::Pixbuf * pb = NULL;
+ pb = sp_image_repr_read_image (
+ this->getRepr()->attribute("xlink:href"),
+ this->getRepr()->attribute("sodipodi:absref"),
+ this->document->getBase());
+
+ if (pb) {
+ ret = g_strdup_printf(_("%d &#215; %d: %s"),
+ pb->width(),
+ pb->height(),
+ href_desc);
+ delete pb;
+ }
+ }
g_free(href_desc);
return ret;
@@ -793,6 +788,60 @@ void sp_embed_image(Inkscape::XML::Node *image_node, Inkscape::Pixbuf *pb)
if (free_data) g_free(data);
}
+void sp_embed_svg(Inkscape::XML::Node *image_node, std::string const &fn)
+{
+ if (!g_file_test(fn.c_str(), G_FILE_TEST_EXISTS)) {
+ return;
+ }
+ GStatBuf stdir;
+ int val = g_stat(fn.c_str(), &stdir);
+ if (val == 0 && stdir.st_mode & S_IFDIR){
+ return;
+ }
+
+ // we need to load the entire file into memory,
+ // since we'll store it as MIME data
+ gchar *data = NULL;
+ gsize len = 0;
+ GError *error = NULL;
+
+ if (g_file_get_contents(fn.c_str(), &data, &len, &error)) {
+
+ if (error != NULL) {
+ std::cerr << "Pixbuf::create_from_file: " << error->message << std::endl;
+ std::cerr << " (" << fn << ")" << std::endl;
+ return;
+ }
+
+ std::string data_mimetype = "image/svg+xml";
+
+
+ // 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 + 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.c_str());
+
+ gint state = 0;
+ gint save = 0;
+ gsize written = 0;
+ written += g_base64_encode_step(reinterpret_cast<guchar *>(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);
+ g_free(data);
+ }
+}
+
void sp_image_refresh_if_outdated( SPImage* image )
{
if ( image->href && image->pixbuf && image->pixbuf->modificationTime()) {
diff --git a/src/object/sp-image.h b/src/object/sp-image.h
index a5dd84fe2..9a45f819c 100644
--- a/src/object/sp-image.h
+++ b/src/object/sp-image.h
@@ -63,12 +63,12 @@ public:
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
void apply_profile(Inkscape::Pixbuf *pixbuf);
#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- bool on_construct;
};
/* Return duplicate of curve or NULL */
SPCurve *sp_image_get_curve (SPImage *image);
void sp_embed_image(Inkscape::XML::Node *imgnode, Inkscape::Pixbuf *pb);
+void sp_embed_svg(Inkscape::XML::Node *image_node, std::string const &fn);
void sp_image_refresh_if_outdated( SPImage* image );
#endif