Line data Source code
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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "pdfexport.hxx"
22 : #include "impdialog.hxx"
23 :
24 : #include "pdf.hrc"
25 : #include "tools/urlobj.hxx"
26 : #include "tools/fract.hxx"
27 : #include "tools/poly.hxx"
28 : #include "vcl/mapmod.hxx"
29 : #include "vcl/virdev.hxx"
30 : #include "vcl/metaact.hxx"
31 : #include "vcl/gdimtf.hxx"
32 : #include "vcl/jobset.hxx"
33 : #include "vcl/bmpacc.hxx"
34 : #include "vcl/svapp.hxx"
35 : #include "toolkit/awt/vclxdevice.hxx"
36 : #include "unotools/localfilehelper.hxx"
37 : #include "svtools/FilterConfigItem.hxx"
38 : #include "svtools/filter.hxx"
39 : #include "svl/solar.hrc"
40 : #include "comphelper/string.hxx"
41 : #include "comphelper/storagehelper.hxx"
42 : #include "unotools/streamwrap.hxx"
43 : #include "com/sun/star/io/XSeekable.hpp"
44 :
45 : #include "basegfx/polygon/b2dpolygon.hxx"
46 : #include "basegfx/polygon/b2dpolypolygon.hxx"
47 : #include "basegfx/polygon/b2dpolygontools.hxx"
48 :
49 : #include "unotools/saveopt.hxx" // only for testing of relative saving options in PDF
50 :
51 : #include "vcl/graphictools.hxx"
52 : #include "com/sun/star/beans/XPropertySet.hpp"
53 : #include "com/sun/star/configuration/theDefaultProvider.hpp"
54 : #include "com/sun/star/awt/Rectangle.hpp"
55 : #include "com/sun/star/awt/XDevice.hpp"
56 : #include "com/sun/star/util/MeasureUnit.hpp"
57 : #include "com/sun/star/frame/XModel.hpp"
58 : #include "com/sun/star/frame/ModuleManager.hpp"
59 : #include "com/sun/star/frame/XStorable.hpp"
60 : #include "com/sun/star/frame/XController.hpp"
61 : #include "com/sun/star/document/XDocumentProperties.hpp"
62 : #include "com/sun/star/document/XDocumentPropertiesSupplier.hpp"
63 : #include "com/sun/star/container/XNameAccess.hpp"
64 : #include "com/sun/star/view/XViewSettingsSupplier.hpp"
65 : #include "com/sun/star/task/XInteractionRequest.hpp"
66 : #include "com/sun/star/task/PDFExportException.hpp"
67 :
68 : #include "unotools/configmgr.hxx"
69 : #include "cppuhelper/exc_hlp.hxx"
70 : #include "cppuhelper/compbase1.hxx"
71 : #include "cppuhelper/basemutex.hxx"
72 :
73 : #include "com/sun/star/lang/XServiceInfo.hpp"
74 : #include "com/sun/star/drawing/XShapes.hpp"
75 : #include "com/sun/star/graphic/XGraphicProvider.hpp"
76 :
77 : using namespace ::rtl;
78 : using namespace ::vcl;
79 : using namespace ::com::sun::star;
80 : using namespace ::com::sun::star::uno;
81 : using namespace ::com::sun::star::lang;
82 : using namespace ::com::sun::star::beans;
83 : using namespace ::com::sun::star::view;
84 : using namespace ::com::sun::star::graphic;
85 :
86 : // -------------
87 : // - PDFExport -
88 : // -------------
89 :
90 0 : PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc,
91 : const Reference< task::XStatusIndicator >& rxStatusIndicator,
92 : const Reference< task::XInteractionHandler >& rxIH,
93 : const Reference< lang::XMultiServiceFactory >& xFactory ) :
94 : mxSrcDoc ( rxSrcDoc ),
95 : mxMSF ( xFactory ),
96 : mxStatusIndicator ( rxStatusIndicator ),
97 : mxIH ( rxIH ),
98 : mbUseTaggedPDF ( sal_False ),
99 : mnPDFTypeSelection ( 0 ),
100 : mbExportNotes ( sal_True ),
101 : mbExportNotesPages ( sal_False ),
102 : mbEmbedStandardFonts ( sal_False ),//in preparation for i54636 and i76458.
103 : //already used for i59651 (PDF/A-1)
104 : mbUseTransitionEffects ( sal_True ),
105 : mbExportBookmarks ( sal_True ),
106 : mbExportHiddenSlides ( sal_False ),
107 : mnOpenBookmarkLevels ( -1 ),
108 : mbUseLosslessCompression ( sal_False ),
109 : mbReduceImageResolution ( sal_False ),
110 : mbSkipEmptyPages ( sal_True ),
111 : mbAddStream ( sal_False ),
112 : mnMaxImageResolution ( 300 ),
113 : mnQuality ( 90 ),
114 : mnFormsFormat ( 0 ),
115 : mbExportFormFields ( sal_True ),
116 : mbAllowDuplicateFieldNames ( sal_False ),
117 : mnProgressValue ( 0 ),
118 : mbRemoveTransparencies ( sal_False ),
119 : mbWatermark ( sal_False ),
120 :
121 : mbHideViewerToolbar ( sal_False ),
122 : mbHideViewerMenubar ( sal_False ),
123 : mbHideViewerWindowControls ( sal_False ),
124 : mbFitWindow ( sal_False ),
125 : mbCenterWindow ( sal_False ),
126 : mbOpenInFullScreenMode ( sal_False ),
127 : mbDisplayPDFDocumentTitle ( sal_True ),
128 : mnPDFDocumentMode ( 0 ),
129 : mnPDFDocumentAction ( 0 ),
130 : mnZoom ( 100 ),
131 : mnInitialPage ( 1 ),
132 : mnPDFPageLayout ( 0 ),
133 : mbFirstPageLeft ( sal_False ),
134 :
135 : mbEncrypt ( sal_False ),
136 : mbRestrictPermissions ( sal_False ),
137 : mnPrintAllowed ( 2 ),
138 : mnChangesAllowed ( 4 ),
139 : mbCanCopyOrExtract ( sal_True ),
140 : mbCanExtractForAccessibility( sal_True ),
141 :
142 : //--->i56629
143 : mbExportRelativeFsysLinks ( sal_False ),
144 : mnDefaultLinkAction ( 0 ),
145 : mbConvertOOoTargetToPDFTarget( sal_False ),
146 : mbExportBmkToDest ( sal_False ),
147 0 : mbSignPDF ( false )
148 : {
149 0 : }
150 :
151 : // -----------------------------------------------------------------------------
152 :
153 0 : PDFExport::~PDFExport()
154 : {
155 0 : }
156 :
157 : // -----------------------------------------------------------------------------
158 :
159 0 : sal_Bool PDFExport::ExportSelection( vcl::PDFWriter& rPDFWriter,
160 : Reference< com::sun::star::view::XRenderable >& rRenderable,
161 : const Any& rSelection,
162 : const StringRangeEnumerator& rRangeEnum,
163 : Sequence< PropertyValue >& rRenderOptions,
164 : sal_Int32 nPageCount )
165 : {
166 0 : sal_Bool bRet = sal_False;
167 : try
168 : {
169 0 : Any* pFirstPage = NULL;
170 0 : Any* pLastPage = NULL;
171 :
172 0 : sal_Bool bExportNotesPages = sal_False;
173 :
174 0 : for( sal_Int32 nData = 0, nDataCount = rRenderOptions.getLength(); nData < nDataCount; ++nData )
175 : {
176 0 : if ( rRenderOptions[ nData ].Name == "IsFirstPage" )
177 0 : pFirstPage = &rRenderOptions[ nData ].Value;
178 0 : else if ( rRenderOptions[ nData ].Name == "IsLastPage" )
179 0 : pLastPage = &rRenderOptions[ nData ].Value;
180 0 : else if ( rRenderOptions[ nData ].Name == "ExportNotesPages" )
181 0 : rRenderOptions[ nData ].Value >>= bExportNotesPages;
182 : }
183 :
184 0 : OutputDevice* pOut = rPDFWriter.GetReferenceDevice();
185 :
186 0 : if( pOut )
187 : {
188 0 : vcl::PDFExtOutDevData* pPDFExtOutDevData = PTR_CAST( vcl::PDFExtOutDevData, pOut->GetExtOutDevData() );
189 0 : if ( nPageCount )
190 : {
191 0 : pPDFExtOutDevData->SetIsExportNotesPages( bExportNotesPages );
192 :
193 0 : sal_Int32 nCurrentPage(0);
194 0 : StringRangeEnumerator::Iterator aIter = rRangeEnum.begin();
195 0 : StringRangeEnumerator::Iterator aEnd = rRangeEnum.end();
196 0 : while ( aIter != aEnd )
197 : {
198 0 : Sequence< PropertyValue > aRenderer( rRenderable->getRenderer( *aIter, rSelection, rRenderOptions ) );
199 0 : awt::Size aPageSize;
200 :
201 0 : for( sal_Int32 nProperty = 0, nPropertyCount = aRenderer.getLength(); nProperty < nPropertyCount; ++nProperty )
202 : {
203 0 : if ( aRenderer[ nProperty ].Name == "PageSize" )
204 0 : aRenderer[ nProperty].Value >>= aPageSize;
205 : }
206 :
207 0 : pPDFExtOutDevData->SetCurrentPageNumber( nCurrentPage );
208 :
209 0 : GDIMetaFile aMtf;
210 0 : const MapMode aMapMode( MAP_100TH_MM );
211 0 : const Size aMtfSize( aPageSize.Width, aPageSize.Height );
212 :
213 0 : pOut->Push();
214 0 : pOut->EnableOutput( sal_False );
215 0 : pOut->SetMapMode( aMapMode );
216 :
217 0 : aMtf.SetPrefSize( aMtfSize );
218 0 : aMtf.SetPrefMapMode( aMapMode );
219 0 : aMtf.Record( pOut );
220 :
221 : // #i35176#
222 : // IsLastPage property.
223 0 : const sal_Int32 nCurrentRenderer = *aIter;
224 0 : ++aIter;
225 0 : if ( pLastPage && aIter == aEnd )
226 0 : *pLastPage <<= sal_True;
227 :
228 0 : rRenderable->render( nCurrentRenderer, rSelection, rRenderOptions );
229 :
230 0 : aMtf.Stop();
231 0 : aMtf.WindStart();
232 :
233 0 : if( aMtf.GetActionSize() &&
234 0 : ( !mbSkipEmptyPages || aPageSize.Width || aPageSize.Height ) )
235 0 : bRet = ImplExportPage( rPDFWriter, *pPDFExtOutDevData, aMtf ) || bRet;
236 :
237 0 : pOut->Pop();
238 :
239 0 : if ( mxStatusIndicator.is() )
240 0 : mxStatusIndicator->setValue( mnProgressValue );
241 0 : if ( pFirstPage )
242 0 : *pFirstPage <<= sal_False;
243 :
244 0 : ++mnProgressValue;
245 0 : ++nCurrentPage;
246 0 : }
247 : }
248 : else
249 : {
250 0 : bRet = sal_True; // #i18334# SJ: nPageCount == 0,
251 0 : rPDFWriter.NewPage( 10000, 10000 ); // creating dummy page
252 0 : rPDFWriter.SetMapMode( MAP_100TH_MM ); //
253 : }
254 : }
255 : }
256 0 : catch(const RuntimeException &)
257 : {
258 : }
259 0 : return bRet;
260 : }
261 :
262 : class PDFExportStreamDoc : public vcl::PDFOutputStream
263 : {
264 : Reference< XComponent > m_xSrcDoc;
265 : Sequence< beans::NamedValue > m_aPreparedPassword;
266 : public:
267 0 : PDFExportStreamDoc( const Reference< XComponent >& xDoc, const Sequence<beans::NamedValue>& rPwd )
268 : : m_xSrcDoc( xDoc ),
269 0 : m_aPreparedPassword( rPwd )
270 0 : {}
271 : virtual ~PDFExportStreamDoc();
272 :
273 : virtual void write( const Reference< XOutputStream >& xStream );
274 : };
275 :
276 0 : PDFExportStreamDoc::~PDFExportStreamDoc()
277 : {
278 0 : }
279 :
280 0 : void PDFExportStreamDoc::write( const Reference< XOutputStream >& xStream )
281 : {
282 0 : Reference< com::sun::star::frame::XStorable > xStore( m_xSrcDoc, UNO_QUERY );
283 0 : if( xStore.is() )
284 : {
285 0 : Sequence< beans::PropertyValue > aArgs( 2 + ((m_aPreparedPassword.getLength() > 0) ? 1 : 0) );
286 0 : aArgs.getArray()[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
287 0 : aArgs.getArray()[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) );
288 0 : aArgs.getArray()[1].Value <<= xStream;
289 0 : if( m_aPreparedPassword.getLength() )
290 : {
291 0 : aArgs.getArray()[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionData" ) );
292 0 : aArgs.getArray()[2].Value <<= m_aPreparedPassword;
293 : }
294 :
295 : try
296 : {
297 0 : xStore->storeToURL( OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ),
298 0 : aArgs );
299 : }
300 0 : catch( const IOException& )
301 : {
302 0 : }
303 0 : }
304 0 : }
305 :
306 0 : static OUString getMimetypeForDocument( const Reference< XMultiServiceFactory >& xFactory,
307 : const Reference< XComponent >& xDoc ) throw()
308 : {
309 0 : OUString aDocMimetype;
310 : // get document service name
311 0 : Reference< com::sun::star::frame::XStorable > xStore( xDoc, UNO_QUERY );
312 0 : Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(comphelper::getComponentContext( xFactory )) );
313 0 : if( xStore.is() )
314 : {
315 0 : OUString aDocServiceName = xModuleManager->identify( Reference< XInterface >( xStore, uno::UNO_QUERY ) );
316 0 : if ( !aDocServiceName.isEmpty() )
317 : {
318 : // get the actual filter name
319 0 : OUString aFilterName;
320 : Reference< lang::XMultiServiceFactory > xConfigProvider(
321 : configuration::theDefaultProvider::get(
322 0 : comphelper::getComponentContext( xFactory ) ) );
323 0 : uno::Sequence< uno::Any > aArgs( 1 );
324 0 : beans::NamedValue aPathProp;
325 0 : aPathProp.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
326 0 : aPathProp.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Setup/Office/Factories/" ) );
327 0 : aArgs[0] <<= aPathProp;
328 :
329 : Reference< container::XNameAccess > xSOFConfig(
330 0 : xConfigProvider->createInstanceWithArguments(
331 : OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) ),
332 0 : aArgs ),
333 0 : uno::UNO_QUERY );
334 :
335 0 : Reference< container::XNameAccess > xApplConfig;
336 0 : xSOFConfig->getByName( aDocServiceName ) >>= xApplConfig;
337 0 : if ( xApplConfig.is() )
338 : {
339 0 : xApplConfig->getByName( OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupFactoryActualFilter" ) ) ) >>= aFilterName;
340 0 : if( !aFilterName.isEmpty() )
341 : {
342 : // find the related type name
343 0 : OUString aTypeName;
344 : Reference< container::XNameAccess > xFilterFactory(
345 0 : xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.FilterFactory" )) ),
346 0 : uno::UNO_QUERY );
347 :
348 0 : Sequence< beans::PropertyValue > aFilterData;
349 0 : xFilterFactory->getByName( aFilterName ) >>= aFilterData;
350 0 : for ( sal_Int32 nInd = 0; nInd < aFilterData.getLength(); nInd++ )
351 0 : if ( aFilterData[nInd].Name == "Type" )
352 0 : aFilterData[nInd].Value >>= aTypeName;
353 :
354 0 : if ( !aTypeName.isEmpty() )
355 : {
356 : // find the mediatype
357 : Reference< container::XNameAccess > xTypeDetection(
358 0 : xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.TypeDetection" )) ),
359 0 : UNO_QUERY );
360 :
361 0 : Sequence< beans::PropertyValue > aTypeData;
362 0 : xTypeDetection->getByName( aTypeName ) >>= aTypeData;
363 0 : for ( sal_Int32 nInd = 0; nInd < aTypeData.getLength(); nInd++ )
364 0 : if ( aTypeData[nInd].Name == "MediaType" )
365 0 : aTypeData[nInd].Value >>= aDocMimetype;
366 0 : }
367 : }
368 0 : }
369 0 : }
370 : }
371 0 : return aDocMimetype;
372 : }
373 :
374 0 : sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& rFilterData )
375 : {
376 0 : INetURLObject aURL( rFile );
377 0 : sal_Bool bRet = sal_False;
378 :
379 0 : std::set< PDFWriter::ErrorCode > aErrors;
380 :
381 0 : if( aURL.GetProtocol() != INET_PROT_FILE )
382 : {
383 0 : rtl::OUString aTmp;
384 :
385 0 : if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFile, aTmp ) )
386 0 : aURL = INetURLObject(aTmp);
387 : }
388 :
389 0 : if( aURL.GetProtocol() == INET_PROT_FILE )
390 : {
391 0 : Reference< XRenderable > xRenderable( mxSrcDoc, UNO_QUERY );
392 :
393 0 : if( xRenderable.is() )
394 : {
395 0 : VCLXDevice* pXDevice = new VCLXDevice;
396 0 : OUString aPageRange;
397 0 : Any aSelection;
398 0 : PDFWriter::PDFWriterContext aContext;
399 0 : rtl::OUString aOpenPassword, aPermissionPassword;
400 0 : Reference< beans::XMaterialHolder > xEnc;
401 0 : Sequence< beans::NamedValue > aPreparedPermissionPassword;
402 :
403 :
404 : // getting the string for the creator
405 0 : String aCreator;
406 0 : Reference< XServiceInfo > xInfo( mxSrcDoc, UNO_QUERY );
407 0 : if ( xInfo.is() )
408 : {
409 0 : if ( xInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" )) ) )
410 0 : aCreator.AppendAscii( "Impress" );
411 0 : else if ( xInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" )) ) )
412 0 : aCreator.AppendAscii( "Draw" );
413 0 : else if ( xInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" )) ) )
414 0 : aCreator.AppendAscii( "Writer" );
415 0 : else if ( xInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" )) ) )
416 0 : aCreator.AppendAscii( "Calc" );
417 0 : else if ( xInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.formula.FormulaProperties" )) ) )
418 0 : aCreator.AppendAscii( "Math" );
419 : }
420 :
421 0 : Reference< document::XDocumentPropertiesSupplier > xDocumentPropsSupplier( mxSrcDoc, UNO_QUERY );
422 0 : if ( xDocumentPropsSupplier.is() )
423 : {
424 0 : Reference< document::XDocumentProperties > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties() );
425 0 : if ( xDocumentProps.is() )
426 : {
427 0 : aContext.DocumentInfo.Title = xDocumentProps->getTitle();
428 0 : aContext.DocumentInfo.Author = xDocumentProps->getAuthor();
429 0 : aContext.DocumentInfo.Subject = xDocumentProps->getSubject();
430 0 : aContext.DocumentInfo.Keywords = ::comphelper::string::convertCommaSeparated(xDocumentProps->getKeywords());
431 0 : }
432 : }
433 : // getting the string for the producer
434 : aContext.DocumentInfo.Producer =
435 : utl::ConfigManager::getProductName() +
436 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ")) +
437 0 : utl::ConfigManager::getProductVersion();
438 0 : aContext.DocumentInfo.Creator = aCreator;
439 :
440 0 : for( sal_Int32 nData = 0, nDataCount = rFilterData.getLength(); nData < nDataCount; ++nData )
441 : {
442 0 : if ( rFilterData[ nData ].Name == "PageRange" )
443 0 : rFilterData[ nData ].Value >>= aPageRange;
444 0 : else if ( rFilterData[ nData ].Name == "Selection" )
445 0 : rFilterData[ nData ].Value >>= aSelection;
446 0 : else if ( rFilterData[ nData ].Name == "UseLosslessCompression" )
447 0 : rFilterData[ nData ].Value >>= mbUseLosslessCompression;
448 0 : else if ( rFilterData[ nData ].Name == "Quality" )
449 0 : rFilterData[ nData ].Value >>= mnQuality;
450 0 : else if ( rFilterData[ nData ].Name == "ReduceImageResolution" )
451 0 : rFilterData[ nData ].Value >>= mbReduceImageResolution;
452 0 : else if ( rFilterData[ nData ].Name == "IsSkipEmptyPages" )
453 0 : rFilterData[ nData ].Value >>= mbSkipEmptyPages;
454 0 : else if ( rFilterData[ nData ].Name == "MaxImageResolution" )
455 0 : rFilterData[ nData ].Value >>= mnMaxImageResolution;
456 0 : else if ( rFilterData[ nData ].Name == "UseTaggedPDF" )
457 0 : rFilterData[ nData ].Value >>= mbUseTaggedPDF;
458 0 : else if ( rFilterData[ nData ].Name == "SelectPdfVersion" )
459 0 : rFilterData[ nData ].Value >>= mnPDFTypeSelection;
460 0 : else if ( rFilterData[ nData ].Name == "ExportNotes" )
461 0 : rFilterData[ nData ].Value >>= mbExportNotes;
462 0 : else if ( rFilterData[ nData ].Name == "ExportNotesPages" )
463 0 : rFilterData[ nData ].Value >>= mbExportNotesPages;
464 0 : else if ( rFilterData[ nData ].Name == "EmbedStandardFonts" )
465 0 : rFilterData[ nData ].Value >>= mbEmbedStandardFonts;
466 0 : else if ( rFilterData[ nData ].Name == "UseTransitionEffects" )
467 0 : rFilterData[ nData ].Value >>= mbUseTransitionEffects;
468 0 : else if ( rFilterData[ nData ].Name == "ExportFormFields" )
469 0 : rFilterData[ nData ].Value >>= mbExportFormFields;
470 0 : else if ( rFilterData[ nData ].Name == "FormsType" )
471 0 : rFilterData[ nData ].Value >>= mnFormsFormat;
472 0 : else if ( rFilterData[ nData ].Name == "AllowDuplicateFieldNames" )
473 0 : rFilterData[ nData ].Value >>= mbAllowDuplicateFieldNames;
474 : //viewer properties
475 0 : else if ( rFilterData[ nData ].Name == "HideViewerToolbar" )
476 0 : rFilterData[ nData ].Value >>= mbHideViewerToolbar;
477 0 : else if ( rFilterData[ nData ].Name == "HideViewerMenubar" )
478 0 : rFilterData[ nData ].Value >>= mbHideViewerMenubar;
479 0 : else if ( rFilterData[ nData ].Name == "HideViewerWindowControls" )
480 0 : rFilterData[ nData ].Value >>= mbHideViewerWindowControls;
481 0 : else if ( rFilterData[ nData ].Name == "ResizeWindowToInitialPage" )
482 0 : rFilterData[ nData ].Value >>= mbFitWindow;
483 0 : else if ( rFilterData[ nData ].Name == "CenterWindow" )
484 0 : rFilterData[ nData ].Value >>= mbCenterWindow;
485 0 : else if ( rFilterData[ nData ].Name == "OpenInFullScreenMode" )
486 0 : rFilterData[ nData ].Value >>= mbOpenInFullScreenMode;
487 0 : else if ( rFilterData[ nData ].Name == "DisplayPDFDocumentTitle" )
488 0 : rFilterData[ nData ].Value >>= mbDisplayPDFDocumentTitle;
489 0 : else if ( rFilterData[ nData ].Name == "InitialView" )
490 0 : rFilterData[ nData ].Value >>= mnPDFDocumentMode;
491 0 : else if ( rFilterData[ nData ].Name == "Magnification" )
492 0 : rFilterData[ nData ].Value >>= mnPDFDocumentAction;
493 0 : else if ( rFilterData[ nData ].Name == "Zoom" )
494 0 : rFilterData[ nData ].Value >>= mnZoom;
495 0 : else if ( rFilterData[ nData ].Name == "InitialPage" )
496 0 : rFilterData[ nData ].Value >>= mnInitialPage;
497 0 : else if ( rFilterData[ nData ].Name == "PageLayout" )
498 0 : rFilterData[ nData ].Value >>= mnPDFPageLayout;
499 0 : else if ( rFilterData[ nData ].Name == "FirstPageOnLeft" )
500 0 : rFilterData[ nData ].Value >>= aContext.FirstPageLeft;
501 0 : else if ( rFilterData[ nData ].Name == "IsAddStream" )
502 0 : rFilterData[ nData ].Value >>= mbAddStream;
503 0 : else if ( rFilterData[ nData ].Name == "Watermark" )
504 : {
505 0 : maWatermark = rFilterData[ nData ].Value;
506 0 : mbWatermark = sal_True;
507 : }
508 : //now all the security related properties...
509 0 : else if ( rFilterData[ nData ].Name == "EncryptFile" )
510 0 : rFilterData[ nData ].Value >>= mbEncrypt;
511 0 : else if ( rFilterData[ nData ].Name == "DocumentOpenPassword" )
512 0 : rFilterData[ nData ].Value >>= aOpenPassword;
513 0 : else if ( rFilterData[ nData ].Name == "RestrictPermissions" )
514 0 : rFilterData[ nData ].Value >>= mbRestrictPermissions;
515 0 : else if ( rFilterData[ nData ].Name == "PermissionPassword" )
516 0 : rFilterData[ nData ].Value >>= aPermissionPassword;
517 0 : else if ( rFilterData[ nData ].Name == "PreparedPasswords" )
518 0 : rFilterData[ nData ].Value >>= xEnc;
519 0 : else if ( rFilterData[ nData ].Name == "PreparedPermissionPassword" )
520 0 : rFilterData[ nData ].Value >>= aPreparedPermissionPassword;
521 0 : else if ( rFilterData[ nData ].Name == "Printing" )
522 0 : rFilterData[ nData ].Value >>= mnPrintAllowed;
523 0 : else if ( rFilterData[ nData ].Name == "Changes" )
524 0 : rFilterData[ nData ].Value >>= mnChangesAllowed;
525 0 : else if ( rFilterData[ nData ].Name == "EnableCopyingOfContent" )
526 0 : rFilterData[ nData ].Value >>= mbCanCopyOrExtract;
527 0 : else if ( rFilterData[ nData ].Name == "EnableTextAccessForAccessibilityTools" )
528 0 : rFilterData[ nData ].Value >>= mbCanExtractForAccessibility;
529 : //--->i56629 links extra (relative links and other related stuff)
530 0 : else if ( rFilterData[ nData ].Name == "ExportLinksRelativeFsys" )
531 0 : rFilterData[ nData ].Value >>= mbExportRelativeFsysLinks;
532 0 : else if ( rFilterData[ nData ].Name == "PDFViewSelection" )
533 0 : rFilterData[ nData ].Value >>= mnDefaultLinkAction;
534 0 : else if ( rFilterData[ nData ].Name == "ConvertOOoTargetToPDFTarget" )
535 0 : rFilterData[ nData ].Value >>= mbConvertOOoTargetToPDFTarget;
536 0 : else if ( rFilterData[ nData ].Name == "ExportBookmarksToPDFDestination" )
537 0 : rFilterData[ nData ].Value >>= mbExportBmkToDest;
538 0 : else if ( rFilterData[ nData ].Name == "ExportBookmarks" )
539 0 : rFilterData[ nData ].Value >>= mbExportBookmarks;
540 0 : else if ( rFilterData[ nData ].Name == "ExportHiddenSlides" )
541 0 : rFilterData[ nData ].Value >>= mbExportHiddenSlides;
542 0 : else if ( rFilterData[ nData ].Name == "OpenBookmarkLevels" )
543 0 : rFilterData[ nData ].Value >>= mnOpenBookmarkLevels;
544 0 : else if ( rFilterData[ nData ].Name == "SignPDF" )
545 0 : rFilterData[ nData ].Value >>= mbSignPDF;
546 0 : else if ( rFilterData[ nData ].Name == "SignatureLocation" )
547 0 : rFilterData[ nData ].Value >>= msSignLocation;
548 0 : else if ( rFilterData[ nData ].Name == "SignatureReason" )
549 0 : rFilterData[ nData ].Value >>= msSignReason;
550 0 : else if ( rFilterData[ nData ].Name == "SignatureContactInfo" )
551 0 : rFilterData[ nData ].Value >>= msSignContact;
552 0 : else if ( rFilterData[ nData ].Name == "SignaturePassword" )
553 0 : rFilterData[ nData ].Value >>= msSignPassword;
554 0 : else if ( rFilterData[ nData ].Name == "SignatureCertificate" )
555 0 : rFilterData[ nData ].Value >>= maSignCertificate;
556 : }
557 0 : aContext.URL = aURL.GetMainURL(INetURLObject::DECODE_TO_IURI);
558 :
559 : //set the correct version, depending on user request
560 0 : switch( mnPDFTypeSelection )
561 : {
562 : default:
563 : case 0:
564 0 : aContext.Version = PDFWriter::PDF_1_4;
565 0 : break;
566 : case 1:
567 0 : aContext.Version = PDFWriter::PDF_A_1;
568 : //force the tagged PDF as well
569 0 : mbUseTaggedPDF = sal_True;
570 : //force embedding of standard fonts
571 0 : mbEmbedStandardFonts = sal_True;
572 : //force disabling of form conversion
573 0 : mbExportFormFields = sal_False;
574 : // PDF/A does not allow transparencies
575 0 : mbRemoveTransparencies = sal_True;
576 : // no encryption
577 0 : mbEncrypt = sal_False;
578 0 : xEnc.clear();
579 0 : break;
580 : }
581 :
582 : //copy in context the values default in the contructor or set by the FilterData sequence of properties
583 0 : aContext.Tagged = mbUseTaggedPDF;
584 :
585 : //values used in viewer
586 0 : aContext.HideViewerToolbar = mbHideViewerToolbar;
587 0 : aContext.HideViewerMenubar = mbHideViewerMenubar;
588 0 : aContext.HideViewerWindowControls = mbHideViewerWindowControls;
589 0 : aContext.FitWindow = mbFitWindow;
590 0 : aContext.CenterWindow = mbCenterWindow;
591 0 : aContext.OpenInFullScreenMode = mbOpenInFullScreenMode;
592 0 : aContext.DisplayPDFDocumentTitle = mbDisplayPDFDocumentTitle;
593 0 : aContext.InitialPage = mnInitialPage-1;
594 0 : aContext.OpenBookmarkLevels = mnOpenBookmarkLevels;
595 0 : aContext.EmbedStandardFonts = mbEmbedStandardFonts;
596 :
597 0 : switch( mnPDFDocumentMode )
598 : {
599 : default:
600 : case 0:
601 0 : aContext.PDFDocumentMode = PDFWriter::ModeDefault;
602 0 : break;
603 : case 1:
604 0 : aContext.PDFDocumentMode = PDFWriter::UseOutlines;
605 0 : break;
606 : case 2:
607 0 : aContext.PDFDocumentMode = PDFWriter::UseThumbs;
608 0 : break;
609 : }
610 0 : switch( mnPDFDocumentAction )
611 : {
612 : default:
613 : case 0:
614 0 : aContext.PDFDocumentAction = PDFWriter::ActionDefault;
615 0 : break;
616 : case 1:
617 0 : aContext.PDFDocumentAction = PDFWriter::FitInWindow;
618 0 : break;
619 : case 2:
620 0 : aContext.PDFDocumentAction = PDFWriter::FitWidth;
621 0 : break;
622 : case 3:
623 0 : aContext.PDFDocumentAction = PDFWriter::FitVisible;
624 0 : break;
625 : case 4:
626 0 : aContext.PDFDocumentAction = PDFWriter::ActionZoom;
627 0 : aContext.Zoom = mnZoom;
628 0 : break;
629 : }
630 :
631 0 : switch( mnPDFPageLayout )
632 : {
633 : default:
634 : case 0:
635 0 : aContext.PageLayout = PDFWriter::DefaultLayout;
636 0 : break;
637 : case 1:
638 0 : aContext.PageLayout = PDFWriter::SinglePage;
639 0 : break;
640 : case 2:
641 0 : aContext.PageLayout = PDFWriter::Continuous;
642 0 : break;
643 : case 3:
644 0 : aContext.PageLayout = PDFWriter::ContinuousFacing;
645 0 : break;
646 : }
647 :
648 0 : aContext.FirstPageLeft = mbFirstPageLeft;
649 :
650 : //check if PDF/A, which does not allow encryption
651 0 : if( aContext.Version != PDFWriter::PDF_A_1 )
652 : {
653 : //set values needed in encryption
654 : //set encryption level, fixed, but here it can set by the UI if needed.
655 : // true is 128 bit, false 40
656 : //note that in 40 bit mode the UI needs reworking, since the current UI is meaningfull only for
657 : //128bit security mode
658 0 : aContext.Encryption.Security128bit = sal_True;
659 :
660 : //set check for permission change password
661 : // if not enabled and no permission password, force permissions to default as if PDF where without encryption
662 0 : if( mbRestrictPermissions && (xEnc.is() || !aPermissionPassword.isEmpty()) )
663 : {
664 0 : mbEncrypt = sal_True;
665 : //permission set as desired, done after
666 : }
667 : else
668 : {
669 : //force permission to default
670 0 : mnPrintAllowed = 2 ;
671 0 : mnChangesAllowed = 4 ;
672 0 : mbCanCopyOrExtract = sal_True;
673 0 : mbCanExtractForAccessibility = sal_True ;
674 : }
675 :
676 0 : switch( mnPrintAllowed )
677 : {
678 : case 0: //initialized when aContext is build, means no printing
679 0 : break;
680 : default:
681 : case 2:
682 0 : aContext.Encryption.CanPrintFull = sal_True;
683 : case 1:
684 0 : aContext.Encryption.CanPrintTheDocument = sal_True;
685 0 : break;
686 : }
687 :
688 0 : switch( mnChangesAllowed )
689 : {
690 : case 0: //already in struct PDFSecPermissions CTOR
691 0 : break;
692 : case 1:
693 0 : aContext.Encryption.CanAssemble = sal_True;
694 0 : break;
695 : case 2:
696 0 : aContext.Encryption.CanFillInteractive = sal_True;
697 0 : break;
698 : case 3:
699 0 : aContext.Encryption.CanAddOrModify = sal_True;
700 0 : break;
701 : default:
702 : case 4:
703 : aContext.Encryption.CanModifyTheContent =
704 : aContext.Encryption.CanCopyOrExtract =
705 : aContext.Encryption.CanAddOrModify =
706 0 : aContext.Encryption.CanFillInteractive = sal_True;
707 0 : break;
708 : }
709 :
710 0 : aContext.Encryption.CanCopyOrExtract = mbCanCopyOrExtract;
711 0 : aContext.Encryption.CanExtractForAccessibility = mbCanExtractForAccessibility;
712 0 : if( mbEncrypt && ! xEnc.is() )
713 0 : xEnc = PDFWriter::InitEncryption( aPermissionPassword, aOpenPassword, aContext.Encryption.Security128bit );
714 0 : if( mbEncrypt && !aPermissionPassword.isEmpty() && ! aPreparedPermissionPassword.getLength() )
715 0 : aPreparedPermissionPassword = comphelper::OStorageHelper::CreatePackageEncryptionData( aPermissionPassword );
716 : }
717 : // after this point we don't need the legacy clear passwords anymore
718 : // however they are still inside the passed filter data sequence
719 : // which is sadly out out our control
720 0 : aPermissionPassword = rtl::OUString();
721 0 : aOpenPassword = rtl::OUString();
722 :
723 : /*
724 : * FIXME: the entries are only implicitly defined by the resource file. Should there
725 : * ever be an additional form submit format this could get invalid.
726 : */
727 0 : switch( mnFormsFormat )
728 : {
729 : case 1:
730 0 : aContext.SubmitFormat = PDFWriter::PDF;
731 0 : break;
732 : case 2:
733 0 : aContext.SubmitFormat = PDFWriter::HTML;
734 0 : break;
735 : case 3:
736 0 : aContext.SubmitFormat = PDFWriter::XML;
737 0 : break;
738 : default:
739 : case 0:
740 0 : aContext.SubmitFormat = PDFWriter::FDF;
741 0 : break;
742 : }
743 0 : aContext.AllowDuplicateFieldNames = mbAllowDuplicateFieldNames;
744 :
745 : //get model
746 0 : Reference< frame::XModel > xModel( mxSrcDoc, UNO_QUERY );
747 : {
748 : //---> i56629 Relative link stuff
749 : //set the base URL of the file:
750 : //then base URL
751 0 : aContext.BaseURL = xModel->getURL();
752 : //relative link option is private to PDF Export filter and limited to local filesystem only
753 0 : aContext.RelFsys = mbExportRelativeFsysLinks;
754 : //determine the default acton for PDF links
755 0 : switch( mnDefaultLinkAction )
756 : {
757 : default:
758 : //default: URI, without fragment conversion (the bookmark in PDF may not work)
759 : case 0:
760 0 : aContext.DefaultLinkAction = PDFWriter::URIAction;
761 0 : break;
762 : //view PDF through the reader application
763 : case 1:
764 0 : aContext.ForcePDFAction = sal_True;
765 0 : aContext.DefaultLinkAction = PDFWriter::LaunchAction;
766 0 : break;
767 : //view PDF through an Internet browser
768 : case 2:
769 0 : aContext.DefaultLinkAction = PDFWriter::URIActionDestination;
770 0 : break;
771 : }
772 0 : aContext.ConvertOOoTargetToPDFTarget = mbConvertOOoTargetToPDFTarget;
773 : // check for Link Launch action, not allowed on PDF/A-1
774 : // this code chunk checks when the filter is called from scripting
775 0 : if( aContext.Version == PDFWriter::PDF_A_1 &&
776 : aContext.DefaultLinkAction == PDFWriter::LaunchAction )
777 : { //force the similar allowed URI action
778 0 : aContext.DefaultLinkAction = PDFWriter::URIActionDestination;
779 : //and remove the remote goto action forced on PDF file
780 0 : aContext.ForcePDFAction = sal_False;
781 : }
782 : }
783 :
784 0 : aContext.SignPDF = mbSignPDF;
785 0 : aContext.SignLocation = msSignLocation;
786 0 : aContext.SignContact = msSignContact;
787 0 : aContext.SignReason = msSignReason;
788 0 : aContext.SignPassword = msSignPassword;
789 0 : aContext.SignCertificate = maSignCertificate;
790 :
791 : // all context data set, time to create the printing device
792 0 : PDFWriter* pPDFWriter = new PDFWriter( aContext, xEnc );
793 0 : OutputDevice* pOut = pPDFWriter->GetReferenceDevice();
794 0 : vcl::PDFExtOutDevData* pPDFExtOutDevData = NULL;
795 :
796 : DBG_ASSERT( pOut, "PDFExport::Export: no reference device" );
797 0 : pXDevice->SetOutputDevice( pOut );
798 :
799 0 : if( mbAddStream )
800 : {
801 : // export stream
802 : // get mimetype
803 0 : OUString aSrcMimetype = getMimetypeForDocument( mxMSF, mxSrcDoc );
804 : pPDFWriter->AddStream( aSrcMimetype,
805 0 : new PDFExportStreamDoc( mxSrcDoc, aPreparedPermissionPassword ),
806 : false
807 0 : );
808 : }
809 :
810 0 : if ( pOut )
811 : {
812 : DBG_ASSERT( pOut->GetExtOutDevData() == NULL, "PDFExport: ExtOutDevData already set!!!" );
813 0 : pPDFExtOutDevData = new vcl::PDFExtOutDevData( *pOut );
814 0 : pOut->SetExtOutDevData( pPDFExtOutDevData );
815 0 : pPDFExtOutDevData->SetIsExportNotes( mbExportNotes );
816 0 : pPDFExtOutDevData->SetIsExportTaggedPDF( mbUseTaggedPDF );
817 0 : pPDFExtOutDevData->SetIsExportTransitionEffects( mbUseTransitionEffects );
818 0 : pPDFExtOutDevData->SetFormsFormat( mnFormsFormat );
819 0 : pPDFExtOutDevData->SetIsExportFormFields( mbExportFormFields );
820 0 : pPDFExtOutDevData->SetIsExportBookmarks( mbExportBookmarks );
821 0 : pPDFExtOutDevData->SetIsExportHiddenSlides( mbExportHiddenSlides );
822 0 : pPDFExtOutDevData->SetIsLosslessCompression( mbUseLosslessCompression );
823 0 : pPDFExtOutDevData->SetIsReduceImageResolution( mbReduceImageResolution );
824 0 : pPDFExtOutDevData->SetIsExportNamedDestinations( mbExportBmkToDest );
825 :
826 0 : Sequence< PropertyValue > aRenderOptions( 6 );
827 0 : aRenderOptions[ 0 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "RenderDevice" ) );
828 0 : aRenderOptions[ 0 ].Value <<= Reference< awt::XDevice >( pXDevice );
829 0 : aRenderOptions[ 1 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotesPages" ) );
830 0 : aRenderOptions[ 1 ].Value <<= sal_False;
831 0 : Any& rExportNotesValue = aRenderOptions[ 1 ].Value;
832 0 : aRenderOptions[ 2 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) );
833 0 : aRenderOptions[ 2 ].Value <<= sal_True;
834 0 : aRenderOptions[ 3 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) );
835 0 : aRenderOptions[ 3 ].Value <<= sal_False;
836 0 : aRenderOptions[ 4 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSkipEmptyPages" ) );
837 0 : aRenderOptions[ 4 ].Value <<= mbSkipEmptyPages;
838 0 : aRenderOptions[ 5 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) );
839 0 : aRenderOptions[ 5 ].Value <<= aPageRange;
840 :
841 0 : if( !aPageRange.isEmpty() || !aSelection.hasValue() )
842 : {
843 0 : aSelection = Any();
844 0 : aSelection <<= mxSrcDoc;
845 : }
846 0 : sal_Bool bSecondPassForImpressNotes = sal_False;
847 0 : bool bReChangeToNormalView = false;
848 0 : ::rtl::OUString sShowOnlineLayout( RTL_CONSTASCII_USTRINGPARAM( "ShowOnlineLayout"));
849 0 : uno::Reference< beans::XPropertySet > xViewProperties;
850 :
851 0 : if ( aCreator.EqualsAscii( "Writer" ) )
852 : {
853 : //i92835 if Writer is in web layout mode this has to be switched to normal view and back to web view in the end
854 : try
855 : {
856 0 : Reference< view::XViewSettingsSupplier > xVSettingsSupplier( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
857 0 : xViewProperties = xVSettingsSupplier->getViewSettings();
858 0 : xViewProperties->getPropertyValue( sShowOnlineLayout ) >>= bReChangeToNormalView;
859 0 : if( bReChangeToNormalView )
860 : {
861 0 : xViewProperties->setPropertyValue( sShowOnlineLayout, uno::makeAny( false ) );
862 0 : }
863 : }
864 0 : catch( const uno::Exception& )
865 : {
866 : }
867 :
868 : }
869 :
870 0 : const sal_Int32 nPageCount = xRenderable->getRendererCount( aSelection, aRenderOptions );
871 :
872 0 : if ( mbExportNotesPages && aCreator.EqualsAscii( "Impress" ) )
873 : {
874 0 : uno::Reference< drawing::XShapes > xShapes; // sj: do not allow to export notes when
875 0 : if ( ! ( aSelection >>= xShapes ) ) // exporting a selection -> todo: in the dialog
876 0 : bSecondPassForImpressNotes = sal_True; // the export notes checkbox needs to be disabled
877 : }
878 :
879 0 : if( aPageRange.isEmpty() )
880 : {
881 : aPageRange = OUStringBuffer()
882 0 : .append( static_cast< sal_Int32 >( 1 ) )
883 0 : .append( static_cast< sal_Unicode >( '-' ) )
884 0 : .append( nPageCount ).makeStringAndClear();
885 : }
886 0 : StringRangeEnumerator aRangeEnum( aPageRange, 0, nPageCount-1 );
887 :
888 0 : if ( mxStatusIndicator.is() )
889 : {
890 0 : ResMgr* pResMgr = ResMgr::CreateResMgr( "pdffilter", Application::GetSettings().GetUILanguageTag().getLocale() );
891 0 : if ( pResMgr )
892 : {
893 0 : sal_Int32 nTotalPageCount = aRangeEnum.size();
894 0 : if ( bSecondPassForImpressNotes )
895 0 : nTotalPageCount *= 2;
896 0 : mxStatusIndicator->start( String( ResId( PDF_PROGRESS_BAR, *pResMgr ) ), nTotalPageCount );
897 0 : delete pResMgr;
898 : }
899 : }
900 :
901 0 : if( nPageCount > 0 )
902 0 : bRet = ExportSelection( *pPDFWriter, xRenderable, aSelection, aRangeEnum, aRenderOptions, nPageCount );
903 : else
904 0 : bRet = sal_False;
905 :
906 0 : if ( bRet && bSecondPassForImpressNotes )
907 : {
908 0 : rExportNotesValue <<= sal_True;
909 0 : bRet = ExportSelection( *pPDFWriter, xRenderable, aSelection, aRangeEnum, aRenderOptions, nPageCount );
910 : }
911 0 : if ( mxStatusIndicator.is() )
912 0 : mxStatusIndicator->end();
913 :
914 : // if during the export the doc locale was set copy it to PDF writer
915 0 : const com::sun::star::lang::Locale& rLoc( pPDFExtOutDevData->GetDocumentLocale() );
916 0 : if( !rLoc.Language.isEmpty() )
917 0 : pPDFWriter->SetDocumentLocale( rLoc );
918 :
919 0 : if( bRet )
920 : {
921 0 : pPDFExtOutDevData->PlayGlobalActions( *pPDFWriter );
922 0 : pPDFWriter->Emit();
923 0 : aErrors = pPDFWriter->GetErrors();
924 : }
925 0 : pOut->SetExtOutDevData( NULL );
926 0 : if( bReChangeToNormalView )
927 : {
928 : try
929 : {
930 0 : xViewProperties->setPropertyValue( sShowOnlineLayout, uno::makeAny( true ) );
931 : }
932 0 : catch( const uno::Exception& )
933 : {
934 : }
935 0 : }
936 : }
937 :
938 0 : delete pPDFExtOutDevData;
939 0 : delete pPDFWriter;
940 0 : }
941 : }
942 :
943 : // show eventual errors during export
944 0 : showErrors( aErrors );
945 :
946 0 : return bRet;
947 : }
948 :
949 : namespace
950 : {
951 :
952 : typedef cppu::WeakComponentImplHelper1< task::XInteractionRequest > PDFErrorRequestBase;
953 :
954 0 : class PDFErrorRequest : private cppu::BaseMutex,
955 : public PDFErrorRequestBase
956 : {
957 : task::PDFExportException maExc;
958 : public:
959 : PDFErrorRequest( const task::PDFExportException& i_rExc );
960 :
961 : // XInteractionRequest
962 : virtual uno::Any SAL_CALL getRequest() throw (uno::RuntimeException);
963 : virtual uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL getContinuations() throw (uno::RuntimeException);
964 : };
965 :
966 0 : PDFErrorRequest::PDFErrorRequest( const task::PDFExportException& i_rExc ) :
967 : PDFErrorRequestBase( m_aMutex ),
968 0 : maExc( i_rExc )
969 : {
970 0 : }
971 :
972 0 : uno::Any SAL_CALL PDFErrorRequest::getRequest() throw (uno::RuntimeException)
973 : {
974 0 : osl::MutexGuard const guard( m_aMutex );
975 :
976 0 : uno::Any aRet;
977 0 : aRet <<= maExc;
978 0 : return aRet;
979 : }
980 :
981 0 : uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL PDFErrorRequest::getContinuations() throw (uno::RuntimeException)
982 : {
983 0 : return uno::Sequence< uno::Reference< task::XInteractionContinuation > >();
984 : }
985 :
986 : } // namespace
987 :
988 0 : void PDFExport::showErrors( const std::set< PDFWriter::ErrorCode >& rErrors )
989 : {
990 0 : if( ! rErrors.empty() && mxIH.is() )
991 : {
992 0 : task::PDFExportException aExc;
993 0 : aExc.ErrorCodes.realloc( sal_Int32(rErrors.size()) );
994 0 : sal_Int32 i = 0;
995 0 : for( std::set< PDFWriter::ErrorCode >::const_iterator it = rErrors.begin();
996 0 : it != rErrors.end(); ++it, i++ )
997 : {
998 0 : aExc.ErrorCodes.getArray()[i] = (sal_Int32)*it;
999 : }
1000 0 : Reference< task::XInteractionRequest > xReq( new PDFErrorRequest( aExc ) );
1001 0 : mxIH->handle( xReq );
1002 : }
1003 0 : }
1004 :
1005 : // -----------------------------------------------------------------------------
1006 :
1007 0 : sal_Bool PDFExport::ImplExportPage( PDFWriter& rWriter, PDFExtOutDevData& rPDFExtOutDevData, const GDIMetaFile& rMtf )
1008 : {
1009 0 : const Size aSizePDF( OutputDevice::LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_POINT ) );
1010 0 : Point aOrigin;
1011 0 : Rectangle aPageRect( aOrigin, rMtf.GetPrefSize() );
1012 0 : sal_Bool bRet = sal_True;
1013 :
1014 0 : rWriter.NewPage( aSizePDF.Width(), aSizePDF.Height() );
1015 0 : rWriter.SetMapMode( rMtf.GetPrefMapMode() );
1016 :
1017 0 : vcl::PDFWriter::PlayMetafileContext aCtx;
1018 0 : GDIMetaFile aMtf;
1019 0 : if( mbRemoveTransparencies )
1020 : {
1021 : aCtx.m_bTransparenciesWereRemoved = rWriter.GetReferenceDevice()->
1022 : RemoveTransparenciesFromMetaFile( rMtf, aMtf, mnMaxImageResolution, mnMaxImageResolution,
1023 0 : false, true, mbReduceImageResolution );
1024 : }
1025 : else
1026 : {
1027 0 : aMtf = rMtf;
1028 : }
1029 0 : aCtx.m_nMaxImageResolution = mbReduceImageResolution ? mnMaxImageResolution : 0;
1030 0 : aCtx.m_bOnlyLosslessCompression = mbUseLosslessCompression;
1031 0 : aCtx.m_nJPEGQuality = mnQuality;
1032 :
1033 :
1034 0 : basegfx::B2DRectangle aB2DRect( aPageRect.Left(), aPageRect.Top(), aPageRect.Right(), aPageRect.Bottom() );
1035 0 : rWriter.SetClipRegion( basegfx::B2DPolyPolygon( basegfx::tools::createPolygonFromRect( aB2DRect ) ) );
1036 :
1037 0 : rWriter.PlayMetafile( aMtf, aCtx, &rPDFExtOutDevData );
1038 :
1039 0 : rPDFExtOutDevData.ResetSyncData();
1040 :
1041 0 : if( mbWatermark )
1042 0 : ImplWriteWatermark( rWriter, aSizePDF );
1043 :
1044 0 : return bRet;
1045 : }
1046 :
1047 : // -----------------------------------------------------------------------------
1048 :
1049 0 : void PDFExport::ImplWriteWatermark( PDFWriter& rWriter, const Size& rPageSize )
1050 : {
1051 0 : OUString aText( RTL_CONSTASCII_USTRINGPARAM( "Watermark" ) );
1052 0 : Font aFont( OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica" ) ), Size( 0, 3*rPageSize.Height()/4 ) );
1053 0 : aFont.SetItalic( ITALIC_NONE );
1054 0 : aFont.SetWidthType( WIDTH_NORMAL );
1055 0 : aFont.SetWeight( WEIGHT_NORMAL );
1056 0 : aFont.SetAlign( ALIGN_BOTTOM );
1057 0 : long nTextWidth = rPageSize.Width();
1058 0 : if( rPageSize.Width() < rPageSize.Height() )
1059 : {
1060 0 : nTextWidth = rPageSize.Height();
1061 0 : aFont.SetOrientation( 2700 );
1062 : }
1063 :
1064 0 : if( ! ( maWatermark >>= aText ) )
1065 : {
1066 : // more complicated watermark ?
1067 : }
1068 :
1069 : // adjust font height for text to fit
1070 0 : OutputDevice* pDev = rWriter.GetReferenceDevice();
1071 0 : pDev->Push( PUSH_ALL );
1072 0 : pDev->SetFont( aFont );
1073 0 : pDev->SetMapMode( MapMode( MAP_POINT ) );
1074 0 : int w = 0;
1075 0 : while( ( w = pDev->GetTextWidth( aText ) ) > nTextWidth )
1076 : {
1077 0 : long nNewHeight = aFont.GetHeight() * nTextWidth / w;
1078 0 : if( nNewHeight == aFont.GetHeight() )
1079 : {
1080 0 : nNewHeight--;
1081 0 : if( nNewHeight <= 0 )
1082 0 : break;
1083 : }
1084 0 : aFont.SetHeight( nNewHeight );
1085 0 : pDev->SetFont( aFont );
1086 : }
1087 0 : long nTextHeight = pDev->GetTextHeight();
1088 : // leave some maneuvering room for rounding issues, also
1089 : // some fonts go a little outside ascent/descent
1090 0 : nTextHeight += nTextHeight/20;
1091 0 : pDev->Pop();
1092 :
1093 0 : rWriter.Push( PUSH_ALL );
1094 0 : rWriter.SetMapMode( MapMode( MAP_POINT ) );
1095 0 : rWriter.SetFont( aFont );
1096 0 : rWriter.SetTextColor( COL_LIGHTGREEN );
1097 0 : Point aTextPoint;
1098 0 : Rectangle aTextRect;
1099 0 : if( rPageSize.Width() > rPageSize.Height() )
1100 : {
1101 0 : aTextPoint = Point( (rPageSize.Width()-w)/2,
1102 0 : rPageSize.Height()-(rPageSize.Height()-nTextHeight)/2 );
1103 0 : aTextRect = Rectangle( Point( (rPageSize.Width()-w)/2,
1104 0 : (rPageSize.Height()-nTextHeight)/2 ),
1105 0 : Size( w, nTextHeight ) );
1106 : }
1107 : else
1108 : {
1109 0 : aTextPoint = Point( (rPageSize.Width()-nTextHeight)/2,
1110 0 : (rPageSize.Height()-w)/2 );
1111 0 : aTextRect = Rectangle( aTextPoint, Size( nTextHeight, w ) );
1112 : }
1113 0 : rWriter.SetClipRegion();
1114 0 : rWriter.BeginTransparencyGroup();
1115 0 : rWriter.DrawText( aTextPoint, aText );
1116 0 : rWriter.EndTransparencyGroup( aTextRect, 50 );
1117 0 : rWriter.Pop();
1118 0 : }
1119 :
1120 :
1121 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|