summaryrefslogtreecommitdiff
path: root/writerperfect/source
diff options
context:
space:
mode:
Diffstat (limited to 'writerperfect/source')
-rw-r--r--writerperfect/source/writer/EPUBExportFilter.cxx49
-rw-r--r--writerperfect/source/writer/EPUBExportFilter.hxx7
-rw-r--r--writerperfect/source/writer/exp/xmlimp.cxx106
-rw-r--r--writerperfect/source/writer/exp/xmlimp.hxx7
4 files changed, 150 insertions, 19 deletions
diff --git a/writerperfect/source/writer/EPUBExportFilter.cxx b/writerperfect/source/writer/EPUBExportFilter.cxx
index 627d5a4af18f..301bdeb6f460 100644
--- a/writerperfect/source/writer/EPUBExportFilter.cxx
+++ b/writerperfect/source/writer/EPUBExportFilter.cxx
@@ -18,12 +18,16 @@
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/view/XRenderable.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <comphelper/genericpropertyset.hxx>
#include <comphelper/propertysetinfo.hxx>
#include <cppuhelper/supportsservice.hxx>
+#include <svtools/DocumentToGraphicRenderer.hxx>
#include "exp/xmlimp.hxx"
#include "EPUBPackage.hxx"
@@ -103,7 +107,14 @@ sal_Bool EPUBExportFilter::filter(const uno::Sequence<beans::PropertyValue> &rDe
uno::Reference<frame::XModel> xSourceModel(mxSourceDocument, uno::UNO_QUERY);
if (xSourceModel.is())
aSourceURL = xSourceModel->getURL();
- uno::Reference<xml::sax::XDocumentHandler> xExportHandler(new exp::XMLImport(mxContext, aGenerator, aSourceURL, rDescriptor));
+
+ std::vector<std::pair<uno::Sequence<sal_Int8>, Size>> aPageMetafiles;
+#if LIBEPUBGEN_VERSION_SUPPORT
+ if (nLayoutMethod == libepubgen::EPUB_LAYOUT_METHOD_FIXED)
+ CreateMetafiles(aPageMetafiles);
+#endif
+
+ uno::Reference<xml::sax::XDocumentHandler> xExportHandler(new exp::XMLImport(mxContext, aGenerator, aSourceURL, rDescriptor, aPageMetafiles));
uno::Reference<lang::XInitialization> xInitialization(mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.Writer.XMLOasisExporter", mxContext), uno::UNO_QUERY);
@@ -111,7 +122,7 @@ sal_Bool EPUBExportFilter::filter(const uno::Sequence<beans::PropertyValue> &rDe
comphelper::PropertyMapEntry const aInfoMap[] =
{
{OUString("BaseURI"), 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0},
- {OUString(), 0, css::uno::Type(), 0, 0}
+ {OUString(), 0, uno::Type(), 0, 0}
};
uno::Reference<beans::XPropertySet> xInfoSet(comphelper::GenericPropertySet_CreateInstance(new comphelper::PropertySetInfo(aInfoMap)));
xInfoSet->setPropertyValue("BaseURI", uno::makeAny(aSourceURL));
@@ -120,9 +131,43 @@ sal_Bool EPUBExportFilter::filter(const uno::Sequence<beans::PropertyValue> &rDe
uno::Reference<document::XExporter> xExporter(xInitialization, uno::UNO_QUERY);
xExporter->setSourceDocument(mxSourceDocument);
uno::Reference<document::XFilter> xFilter(xInitialization, uno::UNO_QUERY);
+
return xFilter->filter(rDescriptor);
}
+void EPUBExportFilter::CreateMetafiles(std::vector<std::pair<uno::Sequence<sal_Int8>, Size>> &rPageMetafiles)
+{
+ DocumentToGraphicRenderer aRenderer(mxSourceDocument, /*bSelectionOnly=*/false);
+ uno::Reference<frame::XModel> xModel(mxSourceDocument, uno::UNO_QUERY);
+ if (!xModel.is())
+ return;
+
+ uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
+ if (!xTextViewCursorSupplier.is())
+ return;
+
+ uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
+ if (!xCursor.is())
+ return;
+
+ xCursor->jumpToLastPage();
+ sal_Int16 nPages = xCursor->getPage();
+ for (sal_Int16 nPage = 1; nPage <= nPages; ++nPage)
+ {
+ Size aDocumentSizePixel = aRenderer.getDocumentSizeInPixels(nPage);
+ Graphic aGraphic = aRenderer.renderToGraphic(nPage, aDocumentSizePixel, aDocumentSizePixel, COL_WHITE);
+ const GDIMetaFile &rGDIMetaFile = aGraphic.GetGDIMetaFile();
+ SvMemoryStream aMemoryStream;
+ const_cast<GDIMetaFile &>(rGDIMetaFile).Write(aMemoryStream);
+ uno::Sequence<sal_Int8> aSequence(static_cast<const sal_Int8 *>(aMemoryStream.GetData()), aMemoryStream.Tell());
+
+ Size aLogic = aRenderer.getDocumentSizeIn100mm(nPage);
+ // Get the CSS pixel size of the page (mm100 -> pixel using 96 DPI, independent from system DPI).
+ Size aCss(static_cast<double>(aLogic.getWidth()) / 26.4583, static_cast<double>(aLogic.getHeight()) / 26.4583);
+ rPageMetafiles.emplace_back(aSequence, aCss);
+ }
+}
+
void EPUBExportFilter::cancel()
{
}
diff --git a/writerperfect/source/writer/EPUBExportFilter.hxx b/writerperfect/source/writer/EPUBExportFilter.hxx
index e96b0a84b695..7a97f4a40852 100644
--- a/writerperfect/source/writer/EPUBExportFilter.hxx
+++ b/writerperfect/source/writer/EPUBExportFilter.hxx
@@ -10,12 +10,15 @@
#ifndef INCLUDED_WRITERPERFECT_SOURCE_WRITER_EPUBEXPORTFILTER_HXX
#define INCLUDED_WRITERPERFECT_SOURCE_WRITER_EPUBEXPORTFILTER_HXX
+#include <vector>
+
#include <cppuhelper/implbase.hxx>
#include <com/sun/star/document/XFilter.hpp>
#include <com/sun/star/document/XExporter.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
+#include <tools/gen.hxx>
namespace writerperfect
{
@@ -52,6 +55,10 @@ public:
static sal_Int32 GetDefaultSplitMethod();
/// Gives the default layout method.
static sal_Int32 GetDefaultLayoutMethod();
+
+private:
+ /// Create page metafiles in case of fixed layout.
+ void CreateMetafiles(std::vector<std::pair<css::uno::Sequence<sal_Int8>, Size>> &rPageMetafiles);
};
} // namespace writerperfect
diff --git a/writerperfect/source/writer/exp/xmlimp.cxx b/writerperfect/source/writer/exp/xmlimp.cxx
index 1d245401aea6..4686cd95ad64 100644
--- a/writerperfect/source/writer/exp/xmlimp.cxx
+++ b/writerperfect/source/writer/exp/xmlimp.cxx
@@ -12,9 +12,11 @@
#include <initializer_list>
#include <unordered_map>
+#include <com/sun/star/svg/XSVGWriter.hpp>
#include <com/sun/star/uri/UriReferenceFactory.hpp>
#include <com/sun/star/xml/sax/InputSource.hpp>
#include <com/sun/star/xml/sax/Parser.hpp>
+#include <com/sun/star/xml/sax/Writer.hpp>
#include <rtl/uri.hxx>
#include <tools/stream.hxx>
#include <tools/urlobj.hxx>
@@ -210,7 +212,7 @@ class XMLBodyContext : public XMLImportContext
public:
XMLBodyContext(XMLImport &rImport);
- rtl::Reference<XMLImportContext> CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/) override;
+ rtl::Reference<XMLImportContext> CreateChildContext(const OUString &rName, const uno::Reference<xml::sax::XAttributeList> &/*xAttribs*/) override;
};
XMLBodyContext::XMLBodyContext(XMLImport &rImport)
@@ -218,7 +220,7 @@ XMLBodyContext::XMLBodyContext(XMLImport &rImport)
{
}
-rtl::Reference<XMLImportContext> XMLBodyContext::CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
+rtl::Reference<XMLImportContext> XMLBodyContext::CreateChildContext(const OUString &rName, const uno::Reference<xml::sax::XAttributeList> &/*xAttribs*/)
{
if (rName == "office:text")
return new XMLBodyContentContext(mrImport);
@@ -231,7 +233,10 @@ class XMLOfficeDocContext : public XMLImportContext
public:
XMLOfficeDocContext(XMLImport &rImport);
- rtl::Reference<XMLImportContext> CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/) override;
+ rtl::Reference<XMLImportContext> CreateChildContext(const OUString &rName, const uno::Reference<xml::sax::XAttributeList> &/*xAttribs*/) override;
+
+ // Handles metafile for a single page.
+ void HandleFixedLayoutPage(const uno::Sequence<sal_Int8> &rPage, const Size &rSize, bool bFirst);
};
XMLOfficeDocContext::XMLOfficeDocContext(XMLImport &rImport)
@@ -239,26 +244,85 @@ XMLOfficeDocContext::XMLOfficeDocContext(XMLImport &rImport)
{
}
-rtl::Reference<XMLImportContext> XMLOfficeDocContext::CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
+rtl::Reference<XMLImportContext> XMLOfficeDocContext::CreateChildContext(const OUString &rName, const uno::Reference<xml::sax::XAttributeList> &/*xAttribs*/)
{
- if (rName == "office:body")
- return new XMLBodyContext(mrImport);
- else if (rName == "office:meta")
+ if (rName == "office:meta")
return new XMLMetaDocumentContext(mrImport);
- else if (rName == "office:automatic-styles")
+ if (rName == "office:automatic-styles")
return new XMLStylesContext(mrImport, XMLStylesContext::StyleType_AUTOMATIC);
- else if (rName == "office:styles")
+ if (rName == "office:styles")
return new XMLStylesContext(mrImport, XMLStylesContext::StyleType_NONE);
- else if (rName == "office:font-face-decls")
+ if (rName == "office:font-face-decls")
return new XMLFontFaceDeclsContext(mrImport);
- else if (rName == "office:master-styles")
+ if (rName == "office:master-styles")
return new XMLStylesContext(mrImport, XMLStylesContext::StyleType_MASTER);
+ if (rName == "office:body")
+ {
+ if (mrImport.GetPageMetafiles().empty())
+ return new XMLBodyContext(mrImport);
+ else
+ {
+ // Ignore text from doc model in the fixed layout case, instead
+ // insert the page metafiles.
+ bool bFirst = true;
+ for (const auto &rPage : mrImport.GetPageMetafiles())
+ {
+ HandleFixedLayoutPage(rPage.first, rPage.second, bFirst);
+ if (bFirst)
+ bFirst = false;
+ }
+ }
+ }
return nullptr;
}
-XMLImport::XMLImport(const uno::Reference<uno::XComponentContext> &xContext, librevenge::RVNGTextInterface &rGenerator, const OUString &rURL, const uno::Sequence<beans::PropertyValue> &rDescriptor)
+void XMLOfficeDocContext::HandleFixedLayoutPage(const uno::Sequence<sal_Int8> &rPage, const Size &rSize, bool bFirst)
+{
+ uno::Reference<uno::XComponentContext> xCtx = mrImport.GetComponentContext();
+ uno::Reference<xml::sax::XWriter> xSaxWriter = xml::sax::Writer::create(xCtx);
+ if (!xSaxWriter.is())
+ return;
+
+ uno::Sequence<uno::Any> aArguments;
+ uno::Reference<svg::XSVGWriter> xSVGWriter(xCtx->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.svg.SVGWriter", aArguments, xCtx), uno::UNO_QUERY);
+ if (!xSVGWriter.is())
+ return;
+
+ SvMemoryStream aMemoryStream;
+ xSaxWriter->setOutputStream(new utl::OStreamWrapper(aMemoryStream));
+
+ xSVGWriter->write(xSaxWriter, rPage);
+
+ // Have all the info, invoke libepubgen.
+ librevenge::RVNGPropertyList aPageProperties;
+ // Pixel -> inch.
+ double fWidth = rSize.getWidth();
+ fWidth /= 96;
+ aPageProperties.insert("fo:page-width", fWidth);
+ double fHeight = rSize.getHeight();
+ fHeight /= 96;
+ aPageProperties.insert("fo:page-height", fHeight);
+ mrImport.GetGenerator().openPageSpan(aPageProperties);
+ librevenge::RVNGPropertyList aParagraphProperties;
+ if (!bFirst)
+ // All pages except the first one needs a page break before the page
+ // metafile.
+ aParagraphProperties.insert("fo:break-before", "page");
+ mrImport.GetGenerator().openParagraph(aParagraphProperties);
+ librevenge::RVNGPropertyList aImageProperties;
+ aImageProperties.insert("librevenge:mime-type", "image/svg+xml");
+ librevenge::RVNGBinaryData aBinaryData;
+ aBinaryData.append(static_cast<const unsigned char *>(aMemoryStream.GetBuffer()), aMemoryStream.GetSize());
+ aImageProperties.insert("office:binary-data", aBinaryData);
+ mrImport.GetGenerator().insertBinaryObject(aImageProperties);
+ mrImport.GetGenerator().closeParagraph();
+ mrImport.GetGenerator().closePageSpan();
+}
+
+XMLImport::XMLImport(const uno::Reference<uno::XComponentContext> &xContext, librevenge::RVNGTextInterface &rGenerator, const OUString &rURL, const uno::Sequence<beans::PropertyValue> &rDescriptor, const std::vector<std::pair<uno::Sequence<sal_Int8>, Size>> &rPageMetafiles)
: mrGenerator(rGenerator),
- mxContext(xContext)
+ mxContext(xContext),
+ mrPageMetafiles(rPageMetafiles)
{
uno::Sequence<beans::PropertyValue> aFilterData;
for (sal_Int32 i = 0; i < rDescriptor.getLength(); ++i)
@@ -351,7 +415,17 @@ bool XMLImport::IsPageSpanOpened() const
return mbPageSpanOpened;
}
-rtl::Reference<XMLImportContext> XMLImport::CreateContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
+const std::vector<std::pair<uno::Sequence<sal_Int8>, Size>> &XMLImport::GetPageMetafiles() const
+{
+ return mrPageMetafiles;
+}
+
+const uno::Reference<uno::XComponentContext> &XMLImport::GetComponentContext() const
+{
+ return mxContext;
+}
+
+rtl::Reference<XMLImportContext> XMLImport::CreateContext(const OUString &rName, const uno::Reference<xml::sax::XAttributeList> &/*xAttribs*/)
{
if (rName == "office:document")
return new XMLOfficeDocContext(*this);
@@ -458,7 +532,7 @@ void XMLImport::endDocument()
mrGenerator.endDocument();
}
-void XMLImport::startElement(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs)
+void XMLImport::startElement(const OUString &rName, const uno::Reference<xml::sax::XAttributeList> &xAttribs)
{
rtl::Reference<XMLImportContext> xContext;
if (!maContexts.empty())
@@ -500,7 +574,7 @@ void XMLImport::processingInstruction(const OUString &/*rTarget*/, const OUStrin
{
}
-void XMLImport::setDocumentLocator(const css::uno::Reference<css::xml::sax::XLocator> &/*xLocator*/)
+void XMLImport::setDocumentLocator(const uno::Reference<xml::sax::XLocator> &/*xLocator*/)
{
}
diff --git a/writerperfect/source/writer/exp/xmlimp.hxx b/writerperfect/source/writer/exp/xmlimp.hxx
index aeec06bde727..c5a84852603b 100644
--- a/writerperfect/source/writer/exp/xmlimp.hxx
+++ b/writerperfect/source/writer/exp/xmlimp.hxx
@@ -12,6 +12,7 @@
#include <map>
#include <stack>
+#include <vector>
#include <librevenge/librevenge.h>
@@ -22,6 +23,7 @@
#include <cppuhelper/implbase.hxx>
#include <rtl/ref.hxx>
+#include <tools/gen.hxx>
namespace writerperfect
{
@@ -61,9 +63,10 @@ class XMLImport : public cppu::WeakImplHelper
css::uno::Reference<css::uri::XUriReferenceFactory> mxUriReferenceFactory;
OUString maMediaDir;
bool mbPageSpanOpened = false;
+ const std::vector<std::pair<css::uno::Sequence<sal_Int8>, Size>> &mrPageMetafiles;
public:
- XMLImport(const css::uno::Reference<css::uno::XComponentContext> &xContext, librevenge::RVNGTextInterface &rGenerator, const OUString &rURL, const css::uno::Sequence<css::beans::PropertyValue> &rDescriptor);
+ XMLImport(const css::uno::Reference<css::uno::XComponentContext> &xContext, librevenge::RVNGTextInterface &rGenerator, const OUString &rURL, const css::uno::Sequence<css::beans::PropertyValue> &rDescriptor, const std::vector<std::pair<css::uno::Sequence<sal_Int8>, Size>> &rPageMetafiles);
rtl::Reference<XMLImportContext> CreateContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs);
@@ -89,6 +92,8 @@ public:
bool FillPopupData(const OUString &rURL, librevenge::RVNGPropertyList &rPropList);
void SetPageSpanOpened(bool bPageSpanOpened);
bool IsPageSpanOpened() const;
+ const std::vector<std::pair<css::uno::Sequence<sal_Int8>, Size>> &GetPageMetafiles() const;
+ const css::uno::Reference<css::uno::XComponentContext> &GetComponentContext() const;
// XDocumentHandler
void SAL_CALL startDocument() override;