LibreOffice Module writerperfect (master) 1
EPUBExportFilter.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include "EPUBExportFilter.hxx"
11
12#include <libepubgen/EPUBTextGenerator.h>
13#include <libepubgen/libepubgen-decls.h>
14
15#include <com/sun/star/beans/PropertyAttribute.hpp>
16#include <com/sun/star/beans/XPropertySet.hpp>
17#include <com/sun/star/frame/XModel.hpp>
18#include <com/sun/star/lang/XInitialization.hpp>
19#include <com/sun/star/text/XPageCursor.hpp>
20#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
21#include <com/sun/star/uno/XComponentContext.hpp>
22
28#include <vcl/gdimtf.hxx>
29#include <tools/stream.hxx>
30
31#include "exp/xmlimp.hxx"
32#include "EPUBPackage.hxx"
33
34using namespace com::sun::star;
35
36namespace writerperfect
37{
39 : mxContext(std::move(xContext))
40{
41}
42
43sal_Int32 EPUBExportFilter::GetDefaultVersion() { return 30; }
44
46{
47 return libepubgen::EPUB_SPLIT_METHOD_HEADING;
48}
49
51{
52 return libepubgen::EPUB_LAYOUT_METHOD_REFLOWABLE;
53}
54
56{
58 sal_Int32 nSplitMethod = EPUBExportFilter::GetDefaultSplitMethod();
59 sal_Int32 nLayoutMethod = EPUBExportFilter::GetDefaultLayoutMethod();
61 OUString aFilterOptions;
62 for (const auto& rProp : rDescriptor)
63 {
64 if (rProp.Name == "FilterData")
65 rProp.Value >>= aFilterData;
66 else if (rProp.Name == "FilterOptions")
67 rProp.Value >>= aFilterOptions;
68 }
69
70 if (aFilterOptions == "layout=fixed")
71 nLayoutMethod = libepubgen::EPUB_LAYOUT_METHOD_FIXED;
72
73 for (const auto& rProp : std::as_const(aFilterData))
74 {
75 if (rProp.Name == "EPUBVersion")
76 rProp.Value >>= nVersion;
77 else if (rProp.Name == "EPUBSplitMethod")
78 rProp.Value >>= nSplitMethod;
79 else if (rProp.Name == "EPUBLayoutMethod")
80 rProp.Value >>= nLayoutMethod;
81 }
82
83 // Build the export filter chain: the package has direct access to the ZIP
84 // file, the flat ODF filter has access to the doc model, everything else
85 // is in-between.
86 EPUBPackage aPackage(mxContext, rDescriptor);
87 libepubgen::EPUBTextGenerator aGenerator(&aPackage, nVersion);
88 aGenerator.setOption(libepubgen::EPUB_GENERATOR_OPTION_SPLIT, nSplitMethod);
89 aGenerator.setOption(libepubgen::EPUB_GENERATOR_OPTION_LAYOUT, nLayoutMethod);
90 OUString aSourceURL;
91 uno::Reference<frame::XModel> xSourceModel(mxSourceDocument, uno::UNO_QUERY);
92 if (xSourceModel.is())
93 aSourceURL = xSourceModel->getURL();
94
95 std::vector<exp::FixedLayoutPage> aPageMetafiles;
96 if (nLayoutMethod == libepubgen::EPUB_LAYOUT_METHOD_FIXED)
97 CreateMetafiles(aPageMetafiles);
98
100 new exp::XMLImport(mxContext, aGenerator, aSourceURL, rDescriptor, aPageMetafiles));
101
103 mxContext->getServiceManager()->createInstanceWithContext(
104 "com.sun.star.comp.Writer.XMLOasisExporter", mxContext),
105 uno::UNO_QUERY);
106
107 // A subset of parameters are passed in as a property set.
108 static comphelper::PropertyMapEntry const aInfoMap[]
109 = { { OUString("BaseURI"), 0, cppu::UnoType<OUString>::get(),
110 beans::PropertyAttribute::MAYBEVOID, 0 } };
113 xInfoSet->setPropertyValue("BaseURI", uno::Any(aSourceURL));
114
115 xInitialization->initialize({ uno::Any(xExportHandler), uno::Any(xInfoSet) });
116 uno::Reference<document::XExporter> xExporter(xInitialization, uno::UNO_QUERY);
117 xExporter->setSourceDocument(mxSourceDocument);
118 uno::Reference<document::XFilter> xFilter(xInitialization, uno::UNO_QUERY);
119
120 return xFilter->filter(rDescriptor);
121}
122
123void EPUBExportFilter::CreateMetafiles(std::vector<exp::FixedLayoutPage>& rPageMetafiles)
124{
125 DocumentToGraphicRenderer aRenderer(mxSourceDocument, /*bSelectionOnly=*/false);
127 if (!xModel.is())
128 return;
129
130 uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
131 xModel->getCurrentController(), uno::UNO_QUERY);
132 if (!xTextViewCursorSupplier.is())
133 return;
134
135 uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(),
136 uno::UNO_QUERY);
137 if (!xCursor.is())
138 return;
139
140 xCursor->jumpToLastPage();
141 sal_Int16 nPages = xCursor->getPage();
142 for (sal_Int16 nPage = 1; nPage <= nPages; ++nPage)
143 {
144 Size aDocumentSizePixel = aRenderer.getDocumentSizeInPixels(nPage);
145 Size aLogic = aRenderer.getDocumentSizeIn100mm(nPage);
146 // Get the CSS pixel size of the page (mm100 -> pixel using 96 DPI, independent from system DPI).
147 Size aCss(static_cast<double>(aLogic.getWidth()) / 26.4583,
148 static_cast<double>(aLogic.getHeight()) / 26.4583);
149 Graphic aGraphic = aRenderer.renderToGraphic(nPage, aDocumentSizePixel, aCss, COL_WHITE,
150 /*bExtOutDevData=*/true);
151 auto& rGDIMetaFile = const_cast<GDIMetaFile&>(aGraphic.GetGDIMetaFile());
152
153 // Set preferred map unit and size on the metafile, so the SVG size
154 // will be correct in MM.
155 MapMode aMapMode;
156 aMapMode.SetMapUnit(MapUnit::Map100thMM);
157 rGDIMetaFile.SetPrefMapMode(aMapMode);
158 rGDIMetaFile.SetPrefSize(aLogic);
159
160 SvMemoryStream aMemoryStream;
161 SvmWriter aWriter(aMemoryStream);
162 aWriter.Write(rGDIMetaFile);
163 uno::Sequence<sal_Int8> aSequence(static_cast<const sal_Int8*>(aMemoryStream.GetData()),
164 aMemoryStream.Tell());
165
167 aPage.aMetafile = aSequence;
168 aPage.aCssPixels = aCss;
169 aPage.aChapterNames = aRenderer.getChapterNames();
170 rPageMetafiles.push_back(aPage);
171 }
172}
173
175
177{
178 mxSourceDocument = xDocument;
179}
180
182{
183 return "com.sun.star.comp.Writer.EPUBExportFilter";
184}
185
186sal_Bool EPUBExportFilter::supportsService(const OUString& rServiceName)
187{
188 return cppu::supportsService(this, rServiceName);
189}
190
192{
193 uno::Sequence<OUString> aRet = { OUString("com.sun.star.document.ExportFilter") };
194 return aRet;
195}
196
197extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
199 uno::XComponentContext* pContext, uno::Sequence<uno::Any> const& /*rSeq*/)
200{
201 return cppu::acquire(new EPUBExportFilter(pContext));
202}
203
204} // namespace writerperfect
205
206/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Size getDocumentSizeIn100mm(sal_Int32 nCurrentPage, Point *pDocumentPosition=nullptr, Point *pCalcPagePosition=nullptr, Size *pCalcPageSize=nullptr)
const std::vector< OUString > & getChapterNames() const
Graphic renderToGraphic(sal_Int32 nCurrentPage, Size aDocumentSizePixel, Size aTargetSizePixel, Color aPageColor, bool bExtOutDevData)
Size getDocumentSizeInPixels(sal_Int32 nCurrentPage)
const GDIMetaFile & GetGDIMetaFile() const
void SetMapUnit(MapUnit eUnit)
constexpr tools::Long getHeight() const
constexpr tools::Long getWidth() const
const void * GetData()
sal_uInt64 Tell() const
SvStream & Write(const GDIMetaFile &rMetaFile)
css::uno::Type const & get()
EPUB export XFilter implementation.
css::uno::Reference< css::lang::XComponent > mxSourceDocument
static sal_Int32 GetDefaultSplitMethod()
Gives the default split method.
void CreateMetafiles(std::vector< exp::FixedLayoutPage > &rPageMetafiles)
Create page metafiles in case of fixed layout.
OUString SAL_CALL getImplementationName() override
void SAL_CALL cancel() override
static sal_Int32 GetDefaultVersion()
Gives the default EPUB version.
static sal_Int32 GetDefaultLayoutMethod()
Gives the default layout method.
css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
sal_Bool SAL_CALL filter(const css::uno::Sequence< css::beans::PropertyValue > &rDescriptor) override
void SAL_CALL setSourceDocument(const css::uno::Reference< css::lang::XComponent > &xDocument) override
EPUBExportFilter(css::uno::Reference< css::uno::XComponentContext > xContext)
css::uno::Reference< css::uno::XComponentContext > mxContext
The epub package has direct access to the resulting ZIP file.
Definition: EPUBPackage.hxx:45
ODT export feeds this class to make librevenge calls.
Definition: xmlimp.hxx:69
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
uno::Reference< uno::XComponentContext > mxContext
sal_Int16 nVersion
COMPHELPER_DLLPUBLIC css::uno::Reference< css::beans::XPropertySet > GenericPropertySet_CreateInstance(PropertySetInfo *pInfo)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
SAL_DLLPUBLIC_EXPORT uno::XInterface * com_sun_star_comp_Writer_EPUBExportFilter_get_implementation(uno::XComponentContext *pContext, uno::Sequence< uno::Any > const &)
Contains info about a fixed-layout page.
Definition: xmlimp.hxx:48
std::vector< OUString > aChapterNames
Definition: xmlimp.hxx:51
css::uno::Sequence< sal_Int8 > aMetafile
Definition: xmlimp.hxx:49
Reference< XModel > xModel
unsigned char sal_Bool
signed char sal_Int8