diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-11-29 11:44:55 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-11-29 17:49:20 +0100 |
commit | 389f7b9581ebd6420a8b9f815807d957608ce8a8 (patch) | |
tree | 2375b8f0c0bbacc313b143d58de071700b5d3a74 /writerperfect/source | |
parent | 67eeab179a7e1d8b479d08a38093172531d4c3c9 (diff) |
EPUB export: add support for cover images
Pick them up from <base directory>/<base name>.cover-image.<ext> as a
start.
Change-Id: Ie5ee7c02d6b3271e6e850ca9a2a10ed0bb4a598d
Reviewed-on: https://gerrit.libreoffice.org/45483
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'writerperfect/source')
-rw-r--r-- | writerperfect/source/writer/EPUBExportFilter.cxx | 7 | ||||
-rw-r--r-- | writerperfect/source/writer/exp/xmlimp.cxx | 92 | ||||
-rw-r--r-- | writerperfect/source/writer/exp/xmlimp.hxx | 5 | ||||
-rw-r--r-- | writerperfect/source/writer/exp/xmlmetai.cxx | 1 |
4 files changed, 102 insertions, 3 deletions
diff --git a/writerperfect/source/writer/EPUBExportFilter.cxx b/writerperfect/source/writer/EPUBExportFilter.cxx index b17c57aa784e..2454adddc781 100644 --- a/writerperfect/source/writer/EPUBExportFilter.cxx +++ b/writerperfect/source/writer/EPUBExportFilter.cxx @@ -14,6 +14,7 @@ #include <libepubgen/EPUBTextGenerator.h> #include <libepubgen/libepubgen-decls.h> +#include <com/sun/star/frame/XModel.hpp> #include <com/sun/star/lang/XInitialization.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/xml/sax/XDocumentHandler.hpp> @@ -74,7 +75,11 @@ sal_Bool EPUBExportFilter::filter(const uno::Sequence<beans::PropertyValue> &rDe , nVersion #endif ); - uno::Reference<xml::sax::XDocumentHandler> xExportHandler(new exp::XMLImport(aGenerator)); + OUString aSourceURL; + uno::Reference<frame::XModel> xSourceModel(mxSourceDocument, uno::UNO_QUERY); + if (xSourceModel.is()) + aSourceURL = xSourceModel->getURL(); + uno::Reference<xml::sax::XDocumentHandler> xExportHandler(new exp::XMLImport(aGenerator, aSourceURL, rDescriptor)); uno::Reference<lang::XInitialization> xInitialization(mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.Writer.XMLOasisExporter", mxContext), uno::UNO_QUERY); xInitialization->initialize({uno::makeAny(xExportHandler)}); diff --git a/writerperfect/source/writer/exp/xmlimp.cxx b/writerperfect/source/writer/exp/xmlimp.cxx index 30a7ee03d404..3d7f99cc399e 100644 --- a/writerperfect/source/writer/exp/xmlimp.cxx +++ b/writerperfect/source/writer/exp/xmlimp.cxx @@ -9,6 +9,13 @@ #include "xmlimp.hxx" +#include <initializer_list> +#include <unordered_map> + +#include <rtl/uri.hxx> +#include <tools/stream.hxx> +#include <tools/urlobj.hxx> + #include "xmlfmt.hxx" #include "xmlictxt.hxx" #include "xmlmetai.hxx" @@ -21,6 +28,70 @@ namespace writerperfect namespace exp { +namespace +{ +/// Looks up mime type for a given image extension. +OUString GetMimeType(const OUString &rExtension) +{ + static const std::unordered_map<OUString, OUString> vMimeTypes = + { + {"gif", "image/gif"}, + {"jpg", "image/jpeg"}, + {"png", "image/png"}, + {"svg", "image/svg+xml"}, + }; + + auto it = vMimeTypes.find(rExtension); + return it == vMimeTypes.end() ? OUString() : it->second; +} + +/// Picks up a cover image from the base directory. +OUString FindCoverImage(const OUString &rDocumentBaseURL, OUString &rMimeType) +{ + OUString aRet; + + if (rDocumentBaseURL.isEmpty()) + return aRet; + + INetURLObject aDocumentBaseURL(rDocumentBaseURL); + + static const std::initializer_list<OUStringLiteral> vExtensions = + { + "gif", + "jpg", + "png", + "svg" + }; + + for (const auto &rExtension : vExtensions) + { + try + { + aRet = rtl::Uri::convertRelToAbs(rDocumentBaseURL, aDocumentBaseURL.GetBase() + ".cover-image." + rExtension); + } + catch (const rtl::MalformedUriException &rException) + { + SAL_WARN("writerfilter", "FindCoverImage: convertRelToAbs() failed:" << rException.getMessage()); + } + + if (!aRet.isEmpty()) + { + SvFileStream aStream(aRet, StreamMode::READ); + if (aStream.IsOpen()) + { + rMimeType = GetMimeType(rExtension); + // File exists. + return aRet; + } + else + aRet.clear(); + } + } + + return aRet; +} +} + /// Handler for <office:body>. class XMLBodyContext : public XMLImportContext { @@ -71,9 +142,28 @@ rtl::Reference<XMLImportContext> XMLOfficeDocContext::CreateChildContext(const O return nullptr; } -XMLImport::XMLImport(librevenge::RVNGTextInterface &rGenerator) +XMLImport::XMLImport(librevenge::RVNGTextInterface &rGenerator, const OUString &rURL, const uno::Sequence<beans::PropertyValue> &/*rDescriptor*/) : mrGenerator(rGenerator) { + OUString aMimeType; + OUString aCoverImage = FindCoverImage(rURL, aMimeType); + if (!aCoverImage.isEmpty()) + { + librevenge::RVNGBinaryData aBinaryData; + SvFileStream aStream(aCoverImage, StreamMode::READ); + SvMemoryStream aMemoryStream; + aMemoryStream.WriteStream(aStream); + aBinaryData.append(static_cast<const unsigned char *>(aMemoryStream.GetBuffer()), aMemoryStream.GetSize()); + librevenge::RVNGPropertyList aCoverImageProperties; + aCoverImageProperties.insert("office:binary-data", aBinaryData); + aCoverImageProperties.insert("librevenge:mime-type", aMimeType.toUtf8().getStr()); + maCoverImages.append(aCoverImageProperties); + } +} + +const librevenge::RVNGPropertyListVector &XMLImport::GetCoverImages() +{ + return maCoverImages; } rtl::Reference<XMLImportContext> XMLImport::CreateContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/) diff --git a/writerperfect/source/writer/exp/xmlimp.hxx b/writerperfect/source/writer/exp/xmlimp.hxx index e1b80571d278..b1008f00dbf0 100644 --- a/writerperfect/source/writer/exp/xmlimp.hxx +++ b/writerperfect/source/writer/exp/xmlimp.hxx @@ -15,6 +15,7 @@ #include <librevenge/librevenge.h> +#include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/xml/sax/XDocumentHandler.hpp> #include <cppuhelper/implbase.hxx> @@ -49,9 +50,10 @@ class XMLImport : public cppu::WeakImplHelper std::map<OUString, librevenge::RVNGPropertyList> maTableStyles; std::map<OUString, librevenge::RVNGPropertyList> maAutomaticGraphicStyles; std::map<OUString, librevenge::RVNGPropertyList> maGraphicStyles; + librevenge::RVNGPropertyListVector maCoverImages; public: - XMLImport(librevenge::RVNGTextInterface &rGenerator); + XMLImport(librevenge::RVNGTextInterface &rGenerator, const OUString &rURL, const css::uno::Sequence<css::beans::PropertyValue> &rDescriptor); rtl::Reference<XMLImportContext> CreateContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs); @@ -70,6 +72,7 @@ public: std::map<OUString, librevenge::RVNGPropertyList> &GetRowStyles(); std::map<OUString, librevenge::RVNGPropertyList> &GetTableStyles(); std::map<OUString, librevenge::RVNGPropertyList> &GetGraphicStyles(); + const librevenge::RVNGPropertyListVector &GetCoverImages(); // XDocumentHandler void SAL_CALL startDocument() override; diff --git a/writerperfect/source/writer/exp/xmlmetai.cxx b/writerperfect/source/writer/exp/xmlmetai.cxx index 0d804833bc7a..ad39aa8c39f1 100644 --- a/writerperfect/source/writer/exp/xmlmetai.cxx +++ b/writerperfect/source/writer/exp/xmlmetai.cxx @@ -131,6 +131,7 @@ void XMLMetaInitialCreatorContext::characters(const OUString &rChars) XMLMetaDocumentContext::XMLMetaDocumentContext(XMLImport &rImport) : XMLImportContext(rImport) { + m_aPropertyList.insert("librevenge:cover-images", mrImport.GetCoverImages()); } rtl::Reference<XMLImportContext> XMLMetaDocumentContext::CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/) |