summaryrefslogtreecommitdiff
path: root/writerperfect
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-11-29 11:44:55 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-11-29 17:49:20 +0100
commit389f7b9581ebd6420a8b9f815807d957608ce8a8 (patch)
tree2375b8f0c0bbacc313b143d58de071700b5d3a74 /writerperfect
parent67eeab179a7e1d8b479d08a38093172531d4c3c9 (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')
-rw-r--r--writerperfect/qa/unit/EPUBExportTest.cxx5
-rw-r--r--writerperfect/qa/unit/data/writer/epubexport/meta.cover-image.pngbin0 -> 766 bytes
-rw-r--r--writerperfect/source/writer/EPUBExportFilter.cxx7
-rw-r--r--writerperfect/source/writer/exp/xmlimp.cxx92
-rw-r--r--writerperfect/source/writer/exp/xmlimp.hxx5
-rw-r--r--writerperfect/source/writer/exp/xmlmetai.cxx1
6 files changed, 107 insertions, 3 deletions
diff --git a/writerperfect/qa/unit/EPUBExportTest.cxx b/writerperfect/qa/unit/EPUBExportTest.cxx
index c8fe9a3491bd..e038a7ef6135 100644
--- a/writerperfect/qa/unit/EPUBExportTest.cxx
+++ b/writerperfect/qa/unit/EPUBExportTest.cxx
@@ -326,6 +326,11 @@ void EPUBExportTest::testMeta()
assertXPathContent(mpXmlDoc, "/opf:package/opf:metadata/dc:title", "Title");
assertXPathContent(mpXmlDoc, "/opf:package/opf:metadata/dc:language", "hu");
assertXPathContent(mpXmlDoc, "/opf:package/opf:metadata/opf:meta[@property='dcterms:modified']", "2017-09-27T09:51:19Z");
+
+ // Make sure that cover image next to the source document is picked up.
+ assertXPath(mpXmlDoc, "/opf:package/opf:manifest/opf:item[@href='images/image0001.png']", "properties", "cover-image");
+ assertXPath(mpXmlDoc, "/opf:package/opf:manifest/opf:item[@href='images/image0001.png']", "media-type", "image/png");
+ CPPUNIT_ASSERT(mxZipFile->hasByName("OEBPS/images/image0001.png"));
}
void EPUBExportTest::testParaNamedstyle()
diff --git a/writerperfect/qa/unit/data/writer/epubexport/meta.cover-image.png b/writerperfect/qa/unit/data/writer/epubexport/meta.cover-image.png
new file mode 100644
index 000000000000..fdad35484e7c
--- /dev/null
+++ b/writerperfect/qa/unit/data/writer/epubexport/meta.cover-image.png
Binary files differ
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*/)