diff options
| author | Thomas Holder <thomas@thomas-holder.de> | 2018-11-03 21:15:51 +0000 |
|---|---|---|
| committer | Thomas Holder <thomas@thomas-holder.de> | 2018-11-07 21:27:57 +0000 |
| commit | 81835789f6823079ad1264f4addb26f681c5bd7d (patch) | |
| tree | 43f424eda84722acb1c76c8fc68a4e71bbe8dd1b /src | |
| parent | fix clipboard URL rebasing (diff) | |
| download | inkscape-81835789f6823079ad1264f4addb26f681c5bd7d.tar.gz inkscape-81835789f6823079ad1264f4addb26f681c5bd7d.zip | |
fix bug 1793940 ODG image export
Fixes handling of relative image URIs and data URIs for OpenDocument
drawing (*.odg) export.
Diffstat (limited to 'src')
| -rw-r--r-- | src/extension/internal/odf.cpp | 85 | ||||
| -rw-r--r-- | src/extension/internal/odf.h | 2 | ||||
| -rw-r--r-- | src/util/ziptool.cpp | 7 | ||||
| -rw-r--r-- | src/util/ziptool.h | 1 |
4 files changed, 38 insertions, 57 deletions
diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index c7d0814b4..ae4dfc47c 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -79,6 +79,7 @@ #include "io/inkscapestream.h" #include "io/bufferstream.h" +#include "io/sys.h" #include <util/ziptool.h> #include <iomanip> namespace Inkscape @@ -889,25 +890,6 @@ static Glib::ustring getAttribute( Inkscape::XML::Node *node, char const *attrNa } -/** - * Get the extension suffix from the end of a file name - */ -static Glib::ustring getExtension(const Glib::ustring &fname) -{ - Glib::ustring ext; - - std::string::size_type pos = fname.rfind('.'); - if (pos == fname.npos) - { - ext = ""; - } - else - { - ext = fname.substr(pos); - } - return ext; -} - static Glib::ustring formatTransform(Geom::Affine &tf) { Glib::ustring str; @@ -1049,38 +1031,30 @@ void OdfOutput::preprocess(ZipFile &zf, Inkscape::XML::Node *node) return; } - if (nodeName == "image" || nodeName == "svg:image") - { + if (nodeName == "image" || nodeName == "svg:image") { Glib::ustring href = getAttribute(node, "xlink:href"); - if (href.size() > 0) - { - Glib::ustring oldName = href; - Glib::ustring ext = getExtension(oldName); - if (ext == ".jpeg") - ext = ".jpg"; - if (imageTable.find(oldName) == imageTable.end()) - { - char buf[64]; - snprintf(buf, sizeof(buf), "Pictures/image%u%s", - static_cast<unsigned int>(imageTable.size()), ext.c_str()); - Glib::ustring newName = buf; - imageTable[oldName] = newName; - Glib::ustring comment = "old name was: "; - comment.append(oldName); - Inkscape::URI oldUri(oldName.c_str()); - std::string pathName = oldUri.toNativeFilename(); - ZipEntry *ze = zf.addFile(pathName, comment); - if (ze) - { - ze->setFileName(newName); - } - else - { - g_warning("Could not load image file '%s'", pathName.c_str()); - } + if (href.size() > 0 && imageTable.count(href) == 0) { + try { + auto uri = Inkscape::URI(href.c_str(), docBaseUri.c_str()); + auto mimetype = uri.getMimeType(); + + if (mimetype.substr(0, 6) != "image/") { + return; } + + auto ext = mimetype.substr(6); + auto newName = Glib::ustring("Pictures/image") + std::to_string(imageTable.size()) + "." + ext; + + imageTable[href] = newName; + + auto ze = zf.newEntry(newName, ""); + ze->setUncompressedData(uri.getContents()); + ze->finish(); + } catch (...) { + g_warning("Could not handle URI '%.100s'", href.c_str()); } } + } for (Inkscape::XML::Node *child = node->firstChild() ; child ; child = child->next()) @@ -1122,19 +1096,14 @@ bool OdfOutput::writeManifest(ZipFile &zf) std::map<Glib::ustring, Glib::ustring>::iterator iter; for (iter = imageTable.begin() ; iter!=imageTable.end() ; ++iter) { - Glib::ustring oldName = iter->first; Glib::ustring newName = iter->second; - Glib::ustring ext = getExtension(oldName); - if (ext == ".jpeg") - ext = ".jpg"; + // note: mime subtype was added as file extenion in OdfOutput::preprocess + Glib::ustring mimesubtype = Inkscape::IO::get_file_extension(newName); + outs.printf(" <manifest:file-entry manifest:media-type=\""); - if (ext == ".gif") - outs.printf("image/gif"); - else if (ext == ".png") - outs.printf("image/png"); - else if (ext == ".jpg") - outs.printf("image/jpeg"); + outs.printf("image/"); + outs.printf(mimesubtype.c_str()); outs.printf("\" manifest:full-path=\""); outs.writeString(newName.c_str()); outs.printf("\"/>\n"); @@ -2083,6 +2052,8 @@ void OdfOutput::save(Inkscape::Extension::Output */*mod*/, SPDocument *doc, gcha { reset(); + docBaseUri = Inkscape::URI::from_dirname(doc->getBase()).str(); + ZipFile zf; preprocess(zf, doc->rroot); diff --git a/src/extension/internal/odf.h b/src/extension/internal/odf.h index 08520eb26..a1aca3531 100644 --- a/src/extension/internal/odf.h +++ b/src/extension/internal/odf.h @@ -276,6 +276,8 @@ public: private: + std::string docBaseUri; + void reset(); //cc or dc metadata name/value pairs diff --git a/src/util/ziptool.cpp b/src/util/ziptool.cpp index fc13b836f..a4ad751a0 100644 --- a/src/util/ziptool.cpp +++ b/src/util/ziptool.cpp @@ -2019,6 +2019,13 @@ void ZipEntry::setUncompressedData(const std::vector<unsigned char> &val) uncompressedData = val; } +void ZipEntry::setUncompressedData(const std::string &s) +{ + uncompressedData.clear(); + uncompressedData.reserve(s.size()); + uncompressedData.insert(uncompressedData.begin(), s.begin(), s.end()); +} + /** * */ diff --git a/src/util/ziptool.h b/src/util/ziptool.h index bcaec11f6..8d905f405 100644 --- a/src/util/ziptool.h +++ b/src/util/ziptool.h @@ -318,6 +318,7 @@ public: * */ virtual void setUncompressedData(const std::vector<unsigned char> &val); + virtual void setUncompressedData(const std::string &val); /** * |
