merged tag ooo/DEV300_m102
[LibreOffice.git] / filter / source / pdf / pdfexport.cxx
blob7f50c51d862d47087c25eef77f68cc0661b7db88
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_filter.hxx"
31 #include "pdfexport.hxx"
32 #include "impdialog.hxx"
34 #include "pdf.hrc"
35 #include "tools/urlobj.hxx"
36 #include "tools/fract.hxx"
37 #include "tools/poly.hxx"
38 #include "vcl/mapmod.hxx"
39 #include "vcl/virdev.hxx"
40 #include "vcl/metaact.hxx"
41 #include "vcl/gdimtf.hxx"
42 #include "vcl/jobset.hxx"
43 #include "vcl/salbtype.hxx"
44 #include "vcl/bmpacc.hxx"
45 #include "vcl/svapp.hxx"
46 #include "toolkit/awt/vclxdevice.hxx"
47 #include "unotools/localfilehelper.hxx"
48 #include "unotools/processfactory.hxx"
49 #include "svtools/FilterConfigItem.hxx"
50 #include "svtools/filter.hxx"
51 #include "svl/solar.hrc"
52 #include "comphelper/string.hxx"
53 #include "comphelper/storagehelper.hxx"
54 #include "unotools/streamwrap.hxx"
55 #include "com/sun/star/io/XSeekable.hpp"
57 #include "basegfx/polygon/b2dpolygon.hxx"
58 #include "basegfx/polygon/b2dpolypolygon.hxx"
59 #include "basegfx/polygon/b2dpolygontools.hxx"
61 #include "unotools/saveopt.hxx" // only for testing of relative saving options in PDF
63 #include "vcl/graphictools.hxx"
64 #include "com/sun/star/beans/XPropertySet.hpp"
65 #include "com/sun/star/awt/Rectangle.hpp"
66 #include "com/sun/star/awt/XDevice.hpp"
67 #include "com/sun/star/util/MeasureUnit.hpp"
68 #include "com/sun/star/frame/XModel.hpp"
69 #include "com/sun/star/frame/XModuleManager.hpp"
70 #include "com/sun/star/frame/XStorable.hpp"
71 #include "com/sun/star/frame/XController.hpp"
72 #include "com/sun/star/document/XDocumentProperties.hpp"
73 #include "com/sun/star/document/XDocumentPropertiesSupplier.hpp"
74 #include "com/sun/star/container/XNameAccess.hpp"
75 #include "com/sun/star/view/XViewSettingsSupplier.hpp"
76 #include "com/sun/star/task/XInteractionRequest.hpp"
77 #include "com/sun/star/task/PDFExportException.hpp"
79 #include "unotools/configmgr.hxx"
80 #include "cppuhelper/exc_hlp.hxx"
81 #include "cppuhelper/compbase1.hxx"
82 #include "cppuhelper/basemutex.hxx"
84 #include "com/sun/star/lang/XServiceInfo.hpp"
85 #include "com/sun/star/drawing/XShapes.hpp"
86 #include "com/sun/star/graphic/XGraphicProvider.hpp"
88 using namespace ::rtl;
89 using namespace ::vcl;
90 using namespace ::com::sun::star;
91 using namespace ::com::sun::star::uno;
92 using namespace ::com::sun::star::lang;
93 using namespace ::com::sun::star::beans;
94 using namespace ::com::sun::star::view;
95 using namespace ::com::sun::star::graphic;
97 // -------------
98 // - PDFExport -
99 // -------------
101 PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc,
102 const Reference< task::XStatusIndicator >& rxStatusIndicator,
103 const Reference< task::XInteractionHandler >& rxIH,
104 const Reference< lang::XMultiServiceFactory >& xFactory ) :
105 mxSrcDoc ( rxSrcDoc ),
106 mxMSF ( xFactory ),
107 mxStatusIndicator ( rxStatusIndicator ),
108 mxIH ( rxIH ),
109 mbUseTaggedPDF ( sal_False ),
110 mnPDFTypeSelection ( 0 ),
111 mbExportNotes ( sal_True ),
112 mbExportNotesPages ( sal_False ),
113 mbEmbedStandardFonts ( sal_False ),//in preparation for i54636 and i76458.
114 //already used for i59651 (PDF/A-1)
115 mbUseTransitionEffects ( sal_True ),
116 mbExportBookmarks ( sal_True ),
117 mnOpenBookmarkLevels ( -1 ),
118 mbUseLosslessCompression ( sal_False ),
119 mbReduceImageResolution ( sal_False ),
120 mbSkipEmptyPages ( sal_True ),
121 mbAddStream ( sal_False ),
122 mnMaxImageResolution ( 300 ),
123 mnQuality ( 90 ),
124 mnFormsFormat ( 0 ),
125 mbExportFormFields ( sal_True ),
126 mbAllowDuplicateFieldNames ( sal_False ),
127 mnProgressValue ( 0 ),
128 mbRemoveTransparencies ( sal_False ),
129 mbWatermark ( sal_False ),
131 mbHideViewerToolbar ( sal_False ),
132 mbHideViewerMenubar ( sal_False ),
133 mbHideViewerWindowControls ( sal_False ),
134 mbFitWindow ( sal_False ),
135 mbCenterWindow ( sal_False ),
136 mbOpenInFullScreenMode ( sal_False ),
137 mbDisplayPDFDocumentTitle ( sal_True ),
138 mnPDFDocumentMode ( 0 ),
139 mnPDFDocumentAction ( 0 ),
140 mnZoom ( 100 ),
141 mnInitialPage ( 1 ),
142 mnPDFPageLayout ( 0 ),
143 mbFirstPageLeft ( sal_False ),
145 mbEncrypt ( sal_False ),
146 mbRestrictPermissions ( sal_False ),
147 mnPrintAllowed ( 2 ),
148 mnChangesAllowed ( 4 ),
149 mbCanCopyOrExtract ( sal_True ),
150 mbCanExtractForAccessibility( sal_True ),
152 mnCachePatternId ( -1 ),
154 //--->i56629
155 mbExportRelativeFsysLinks ( sal_False ),
156 mnDefaultLinkAction ( 0 ),
157 mbConvertOOoTargetToPDFTarget( sal_False ),
158 mbExportBmkToDest ( sal_False )
159 //<---
163 // -----------------------------------------------------------------------------
165 PDFExport::~PDFExport()
169 // -----------------------------------------------------------------------------
171 sal_Bool PDFExport::ExportSelection( vcl::PDFWriter& rPDFWriter, Reference< com::sun::star::view::XRenderable >& rRenderable, Any& rSelection,
172 MultiSelection aMultiSelection, Sequence< PropertyValue >& rRenderOptions, sal_Int32 nPageCount )
174 sal_Bool bRet = sal_False;
177 Any* pFirstPage = NULL;
178 Any* pLastPage = NULL;
180 for( sal_Int32 nData = 0, nDataCount = rRenderOptions.getLength(); nData < nDataCount; ++nData )
182 if( rRenderOptions[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) ) )
183 pFirstPage = &rRenderOptions[ nData ].Value;
184 else if( rRenderOptions[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) ) )
185 pLastPage = &rRenderOptions[ nData ].Value;
188 OutputDevice* pOut = rPDFWriter.GetReferenceDevice();
190 if( pOut )
192 vcl::PDFExtOutDevData* pPDFExtOutDevData = PTR_CAST( vcl::PDFExtOutDevData, pOut->GetExtOutDevData() );
193 if ( nPageCount )
195 sal_Int32 nSel = aMultiSelection.FirstSelected();
196 while ( nSel != sal_Int32(SFX_ENDOFSELECTION) )
198 Sequence< PropertyValue > aRenderer( rRenderable->getRenderer( nSel - 1, rSelection, rRenderOptions ) );
199 awt::Size aPageSize;
201 for( sal_Int32 nProperty = 0, nPropertyCount = aRenderer.getLength(); nProperty < nPropertyCount; ++nProperty )
203 if( aRenderer[ nProperty ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) )
204 aRenderer[ nProperty].Value >>= aPageSize;
207 pPDFExtOutDevData->SetCurrentPageNumber( nSel - 1 );
209 GDIMetaFile aMtf;
210 const MapMode aMapMode( MAP_100TH_MM );
211 const Size aMtfSize( aPageSize.Width, aPageSize.Height );
213 pOut->Push();
214 pOut->EnableOutput( sal_False );
215 pOut->SetMapMode( aMapMode );
217 aMtf.SetPrefSize( aMtfSize );
218 aMtf.SetPrefMapMode( aMapMode );
219 aMtf.Record( pOut );
221 // --> FME 2004-10-08 #i35176#
222 // IsLastPage property.
223 const sal_Int32 nCurrentRenderer = nSel - 1;
224 nSel = aMultiSelection.NextSelected();
225 if ( pLastPage && sal_Int32(SFX_ENDOFSELECTION) == nSel )
226 *pLastPage <<= sal_True;
227 // <--
229 rRenderable->render( nCurrentRenderer, rSelection, rRenderOptions );
231 aMtf.Stop();
232 aMtf.WindStart();
234 if( aMtf.GetActionCount() &&
235 ( !mbSkipEmptyPages || aPageSize.Width || aPageSize.Height ) )
236 bRet = ImplExportPage( rPDFWriter, *pPDFExtOutDevData, aMtf ) || bRet;
238 pOut->Pop();
240 if ( mxStatusIndicator.is() )
241 mxStatusIndicator->setValue( mnProgressValue );
242 if ( pFirstPage )
243 *pFirstPage <<= sal_False;
245 ++mnProgressValue;
248 else
250 bRet = sal_True; // #i18334# SJ: nPageCount == 0,
251 rPDFWriter.NewPage( 10000, 10000 ); // creating dummy page
252 rPDFWriter.SetMapMode( MAP_100TH_MM ); //
256 catch( RuntimeException )
259 return bRet;
262 class PDFExportStreamDoc : public vcl::PDFOutputStream
264 Reference< XComponent > m_xSrcDoc;
265 Sequence< beans::NamedValue > m_aPreparedPassword;
266 public:
267 PDFExportStreamDoc( const Reference< XComponent >& xDoc, const Sequence<beans::NamedValue>& rPwd )
268 : m_xSrcDoc( xDoc ),
269 m_aPreparedPassword( rPwd )
271 virtual ~PDFExportStreamDoc();
273 virtual void write( const Reference< XOutputStream >& xStream );
276 PDFExportStreamDoc::~PDFExportStreamDoc()
280 void PDFExportStreamDoc::write( const Reference< XOutputStream >& xStream )
282 Reference< com::sun::star::frame::XStorable > xStore( m_xSrcDoc, UNO_QUERY );
283 if( xStore.is() )
285 Sequence< beans::PropertyValue > aArgs( 2 + ((m_aPreparedPassword.getLength() > 0) ? 1 : 0) );
286 aArgs.getArray()[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
287 aArgs.getArray()[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) );
288 aArgs.getArray()[1].Value <<= xStream;
289 if( m_aPreparedPassword.getLength() )
291 aArgs.getArray()[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionData" ) );
292 aArgs.getArray()[2].Value <<= m_aPreparedPassword;
297 xStore->storeToURL( OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ),
298 aArgs );
300 catch( IOException& )
306 static OUString getMimetypeForDocument( const Reference< XMultiServiceFactory >& xFactory,
307 const Reference< XComponent >& xDoc ) throw()
309 OUString aDocMimetype;
310 // get document service name
311 Reference< com::sun::star::frame::XStorable > xStore( xDoc, UNO_QUERY );
312 Reference< frame::XModuleManager > xModuleManager(
313 xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ) ) ),
314 uno::UNO_QUERY );
315 if( xModuleManager.is() && xStore.is() )
317 OUString aDocServiceName = xModuleManager->identify( Reference< XInterface >( xStore, uno::UNO_QUERY ) );
318 if ( aDocServiceName.getLength() )
320 // get the actual filter name
321 OUString aFilterName;
322 Reference< lang::XMultiServiceFactory > xConfigProvider(
323 xFactory->createInstance(
324 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) ) ),
325 uno::UNO_QUERY );
326 if( xConfigProvider.is() )
328 uno::Sequence< uno::Any > aArgs( 1 );
329 beans::PropertyValue aPathProp;
330 aPathProp.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
331 aPathProp.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Setup/Office/Factories/" ) );
332 aArgs[0] <<= aPathProp;
334 Reference< container::XNameAccess > xSOFConfig(
335 xConfigProvider->createInstanceWithArguments(
336 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) ),
337 aArgs ),
338 uno::UNO_QUERY );
340 Reference< container::XNameAccess > xApplConfig;
341 xSOFConfig->getByName( aDocServiceName ) >>= xApplConfig;
342 if ( xApplConfig.is() )
344 xApplConfig->getByName( OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupFactoryActualFilter" ) ) ) >>= aFilterName;
345 if( aFilterName.getLength() )
347 // find the related type name
348 OUString aTypeName;
349 Reference< container::XNameAccess > xFilterFactory(
350 xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
351 uno::UNO_QUERY );
353 Sequence< beans::PropertyValue > aFilterData;
354 xFilterFactory->getByName( aFilterName ) >>= aFilterData;
355 for ( sal_Int32 nInd = 0; nInd < aFilterData.getLength(); nInd++ )
356 if ( aFilterData[nInd].Name.equalsAscii( "Type" ) )
357 aFilterData[nInd].Value >>= aTypeName;
359 if ( aTypeName.getLength() )
361 // find the mediatype
362 Reference< container::XNameAccess > xTypeDetection(
363 xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
364 UNO_QUERY );
366 Sequence< beans::PropertyValue > aTypeData;
367 xTypeDetection->getByName( aTypeName ) >>= aTypeData;
368 for ( sal_Int32 nInd = 0; nInd < aTypeData.getLength(); nInd++ )
369 if ( aTypeData[nInd].Name.equalsAscii( "MediaType" ) )
370 aTypeData[nInd].Value >>= aDocMimetype;
377 return aDocMimetype;
380 sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& rFilterData )
382 INetURLObject aURL( rFile );
383 OUString aFile;
384 sal_Bool bRet = sal_False;
386 std::set< PDFWriter::ErrorCode > aErrors;
388 if( aURL.GetProtocol() != INET_PROT_FILE )
390 String aTmp;
392 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFile, aTmp ) )
393 aURL = INetURLObject(aTmp);
396 if( aURL.GetProtocol() == INET_PROT_FILE )
398 Reference< XRenderable > xRenderable( mxSrcDoc, UNO_QUERY );
400 if( xRenderable.is() )
402 VCLXDevice* pXDevice = new VCLXDevice;
403 OUString aPageRange;
404 Any aSelection;
405 PDFWriter::PDFWriterContext aContext;
406 rtl::OUString aOpenPassword, aPermissionPassword;
407 Reference< beans::XMaterialHolder > xEnc;
408 Sequence< beans::NamedValue > aPreparedPermissionPassword;
411 // getting the string for the creator
412 String aCreator;
413 Reference< XServiceInfo > xInfo( mxSrcDoc, UNO_QUERY );
414 if ( xInfo.is() )
416 if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.presentation.PresentationDocument" ) ) )
417 aCreator.AppendAscii( "Impress" );
418 else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.drawing.DrawingDocument" ) ) )
419 aCreator.AppendAscii( "Draw" );
420 else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.text.TextDocument" ) ) )
421 aCreator.AppendAscii( "Writer" );
422 else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.sheet.SpreadsheetDocument" ) ) )
423 aCreator.AppendAscii( "Calc" );
424 else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.formula.FormulaProperties" ) ) )
425 aCreator.AppendAscii( "Math" );
428 Reference< document::XDocumentPropertiesSupplier > xDocumentPropsSupplier( mxSrcDoc, UNO_QUERY );
429 if ( xDocumentPropsSupplier.is() )
431 Reference< document::XDocumentProperties > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties() );
432 if ( xDocumentProps.is() )
434 aContext.DocumentInfo.Title = xDocumentProps->getTitle();
435 aContext.DocumentInfo.Author = xDocumentProps->getAuthor();
436 aContext.DocumentInfo.Subject = xDocumentProps->getSubject();
437 aContext.DocumentInfo.Keywords = ::comphelper::string::convertCommaSeparated(xDocumentProps->getKeywords());
440 // getting the string for the producer
441 String aProducer;
442 ::utl::ConfigManager* pMgr = ::utl::ConfigManager::GetConfigManager();
443 if ( pMgr )
445 Any aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
446 ::rtl::OUString sProductName;
447 aProductName >>= sProductName;
448 aProducer = sProductName;
449 aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
450 aProductName >>= sProductName;
451 aProducer.AppendAscii(" ");
452 aProducer += String( sProductName );
454 aContext.DocumentInfo.Producer = aProducer;
455 aContext.DocumentInfo.Creator = aCreator;
457 for( sal_Int32 nData = 0, nDataCount = rFilterData.getLength(); nData < nDataCount; ++nData )
459 if( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ) )
460 rFilterData[ nData ].Value >>= aPageRange;
461 else if( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Selection" ) ) )
462 rFilterData[ nData ].Value >>= aSelection;
463 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "UseLosslessCompression" ) ) )
464 rFilterData[ nData ].Value >>= mbUseLosslessCompression;
465 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Quality" ) ) )
466 rFilterData[ nData ].Value >>= mnQuality;
467 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ReduceImageResolution" ) ) )
468 rFilterData[ nData ].Value >>= mbReduceImageResolution;
469 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSkipEmptyPages" ) ) )
470 rFilterData[ nData ].Value >>= mbSkipEmptyPages;
471 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "MaxImageResolution" ) ) )
472 rFilterData[ nData ].Value >>= mnMaxImageResolution;
473 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "UseTaggedPDF" ) ) )
474 rFilterData[ nData ].Value >>= mbUseTaggedPDF;
475 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectPdfVersion" ) ) )
476 rFilterData[ nData ].Value >>= mnPDFTypeSelection;
477 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotes" ) ) )
478 rFilterData[ nData ].Value >>= mbExportNotes;
479 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotesPages" ) ) )
480 rFilterData[ nData ].Value >>= mbExportNotesPages;
481 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EmbedStandardFonts" ) ) )
482 rFilterData[ nData ].Value >>= mbEmbedStandardFonts;
483 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "UseTransitionEffects" ) ) )
484 rFilterData[ nData ].Value >>= mbUseTransitionEffects;
485 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportFormFields" ) ) )
486 rFilterData[ nData ].Value >>= mbExportFormFields;
487 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "FormsType" ) ) )
488 rFilterData[ nData ].Value >>= mnFormsFormat;
489 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowDuplicateFieldNames" ) ) )
490 rFilterData[ nData ].Value >>= mbAllowDuplicateFieldNames;
491 //viewer properties
492 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerToolbar" ) ) )
493 rFilterData[ nData ].Value >>= mbHideViewerToolbar;
494 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerMenubar" ) ) )
495 rFilterData[ nData ].Value >>= mbHideViewerMenubar;
496 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerWindowControls" ) ) )
497 rFilterData[ nData ].Value >>= mbHideViewerWindowControls;
498 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ResizeWindowToInitialPage" ) ) )
499 rFilterData[ nData ].Value >>= mbFitWindow;
500 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "CenterWindow" ) ) )
501 rFilterData[ nData ].Value >>= mbCenterWindow;
502 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenInFullScreenMode" ) ) )
503 rFilterData[ nData ].Value >>= mbOpenInFullScreenMode;
504 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "DisplayPDFDocumentTitle" ) ) )
505 rFilterData[ nData ].Value >>= mbDisplayPDFDocumentTitle;
506 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "InitialView" ) ) )
507 rFilterData[ nData ].Value >>= mnPDFDocumentMode;
508 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Magnification" ) ) )
509 rFilterData[ nData ].Value >>= mnPDFDocumentAction;
510 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Zoom" ) ) )
511 rFilterData[ nData ].Value >>= mnZoom;
512 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "InitialPage" ) ) )
513 rFilterData[ nData ].Value >>= mnInitialPage;
514 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PageLayout" ) ) )
515 rFilterData[ nData ].Value >>= mnPDFPageLayout;
516 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "FirstPageOnLeft" ) ) )
517 rFilterData[ nData ].Value >>= aContext.FirstPageLeft;
518 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsAddStream" ) ) )
519 rFilterData[ nData ].Value >>= mbAddStream;
520 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Watermark" ) ) )
522 maWatermark = rFilterData[ nData ].Value;
523 mbWatermark = sal_True;
525 //now all the security related properties...
526 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptFile" ) ) )
527 rFilterData[ nData ].Value >>= mbEncrypt;
528 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentOpenPassword" ) ) )
529 rFilterData[ nData ].Value >>= aOpenPassword;
530 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "RestrictPermissions" ) ) )
531 rFilterData[ nData ].Value >>= mbRestrictPermissions;
532 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PermissionPassword" ) ) )
533 rFilterData[ nData ].Value >>= aPermissionPassword;
534 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPasswords" ) ) )
535 rFilterData[ nData ].Value >>= xEnc;
536 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPermissionPassword" ) ) )
537 rFilterData[ nData ].Value >>= aPreparedPermissionPassword;
538 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Printing" ) ) )
539 rFilterData[ nData ].Value >>= mnPrintAllowed;
540 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Changes" ) ) )
541 rFilterData[ nData ].Value >>= mnChangesAllowed;
542 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableCopyingOfContent" ) ) )
543 rFilterData[ nData ].Value >>= mbCanCopyOrExtract;
544 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableTextAccessForAccessibilityTools" ) ) )
545 rFilterData[ nData ].Value >>= mbCanExtractForAccessibility;
546 //--->i56629 links extra (relative links and other related stuff)
547 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportLinksRelativeFsys" ) ) )
548 rFilterData[ nData ].Value >>= mbExportRelativeFsysLinks;
549 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PDFViewSelection" ) ) )
550 rFilterData[ nData ].Value >>= mnDefaultLinkAction;
551 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ConvertOOoTargetToPDFTarget" ) ) )
552 rFilterData[ nData ].Value >>= mbConvertOOoTargetToPDFTarget;
553 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarksToPDFDestination" ) ) )
554 rFilterData[ nData ].Value >>= mbExportBmkToDest;
555 //<---
556 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarks" ) ) )
557 rFilterData[ nData ].Value >>= mbExportBookmarks;
558 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenBookmarkLevels" ) ) )
559 rFilterData[ nData ].Value >>= mnOpenBookmarkLevels;
561 aContext.URL = aURL.GetMainURL(INetURLObject::DECODE_TO_IURI);
563 //set the correct version, depending on user request
564 switch( mnPDFTypeSelection )
566 default:
567 case 0:
568 aContext.Version = PDFWriter::PDF_1_4;
569 break;
570 case 1:
571 aContext.Version = PDFWriter::PDF_A_1;
572 //force the tagged PDF as well
573 mbUseTaggedPDF = sal_True;
574 //force embedding of standard fonts
575 mbEmbedStandardFonts = sal_True;
576 //force disabling of form conversion
577 mbExportFormFields = sal_False;
578 // PDF/A does not allow transparencies
579 mbRemoveTransparencies = sal_True;
580 // no encryption
581 mbEncrypt = sal_False;
582 xEnc.clear();
583 break;
586 //copy in context the values default in the contructor or set by the FilterData sequence of properties
587 aContext.Tagged = mbUseTaggedPDF;
589 //values used in viewer
590 aContext.HideViewerToolbar = mbHideViewerToolbar;
591 aContext.HideViewerMenubar = mbHideViewerMenubar;
592 aContext.HideViewerWindowControls = mbHideViewerWindowControls;
593 aContext.FitWindow = mbFitWindow;
594 aContext.CenterWindow = mbCenterWindow;
595 aContext.OpenInFullScreenMode = mbOpenInFullScreenMode;
596 aContext.DisplayPDFDocumentTitle = mbDisplayPDFDocumentTitle;
597 aContext.InitialPage = mnInitialPage-1;
598 aContext.OpenBookmarkLevels = mnOpenBookmarkLevels;
599 aContext.EmbedStandardFonts = mbEmbedStandardFonts;
601 switch( mnPDFDocumentMode )
603 default:
604 case 0:
605 aContext.PDFDocumentMode = PDFWriter::ModeDefault;
606 break;
607 case 1:
608 aContext.PDFDocumentMode = PDFWriter::UseOutlines;
609 break;
610 case 2:
611 aContext.PDFDocumentMode = PDFWriter::UseThumbs;
612 break;
614 switch( mnPDFDocumentAction )
616 default:
617 case 0:
618 aContext.PDFDocumentAction = PDFWriter::ActionDefault;
619 break;
620 case 1:
621 aContext.PDFDocumentAction = PDFWriter::FitInWindow;
622 break;
623 case 2:
624 aContext.PDFDocumentAction = PDFWriter::FitWidth;
625 break;
626 case 3:
627 aContext.PDFDocumentAction = PDFWriter::FitVisible;
628 break;
629 case 4:
630 aContext.PDFDocumentAction = PDFWriter::ActionZoom;
631 aContext.Zoom = mnZoom;
632 break;
635 switch( mnPDFPageLayout )
637 default:
638 case 0:
639 aContext.PageLayout = PDFWriter::DefaultLayout;
640 break;
641 case 1:
642 aContext.PageLayout = PDFWriter::SinglePage;
643 break;
644 case 2:
645 aContext.PageLayout = PDFWriter::Continuous;
646 break;
647 case 3:
648 aContext.PageLayout = PDFWriter::ContinuousFacing;
649 break;
652 aContext.FirstPageLeft = mbFirstPageLeft;
654 //check if PDF/A, which does not allow encryption
655 if( aContext.Version != PDFWriter::PDF_A_1 )
657 //set values needed in encryption
658 //set encryption level, fixed, but here it can set by the UI if needed.
659 // true is 128 bit, false 40
660 //note that in 40 bit mode the UI needs reworking, since the current UI is meaningfull only for
661 //128bit security mode
662 aContext.Encryption.Security128bit = sal_True;
664 //set check for permission change password
665 // if not enabled and no permission password, force permissions to default as if PDF where without encryption
666 if( mbRestrictPermissions && (xEnc.is() || aPermissionPassword.getLength() > 0) )
668 mbEncrypt = sal_True;
669 //permission set as desired, done after
671 else
673 //force permission to default
674 mnPrintAllowed = 2 ;
675 mnChangesAllowed = 4 ;
676 mbCanCopyOrExtract = sal_True;
677 mbCanExtractForAccessibility = sal_True ;
680 switch( mnPrintAllowed )
682 case 0: //initialized when aContext is build, means no printing
683 break;
684 default:
685 case 2:
686 aContext.Encryption.CanPrintFull = sal_True;
687 case 1:
688 aContext.Encryption.CanPrintTheDocument = sal_True;
689 break;
692 switch( mnChangesAllowed )
694 case 0: //already in struct PDFSecPermissions CTOR
695 break;
696 case 1:
697 aContext.Encryption.CanAssemble = sal_True;
698 break;
699 case 2:
700 aContext.Encryption.CanFillInteractive = sal_True;
701 break;
702 case 3:
703 aContext.Encryption.CanAddOrModify = sal_True;
704 break;
705 default:
706 case 4:
707 aContext.Encryption.CanModifyTheContent =
708 aContext.Encryption.CanCopyOrExtract =
709 aContext.Encryption.CanAddOrModify =
710 aContext.Encryption.CanFillInteractive = sal_True;
711 break;
714 aContext.Encryption.CanCopyOrExtract = mbCanCopyOrExtract;
715 aContext.Encryption.CanExtractForAccessibility = mbCanExtractForAccessibility;
716 if( mbEncrypt && ! xEnc.is() )
717 xEnc = PDFWriter::InitEncryption( aPermissionPassword, aOpenPassword, aContext.Encryption.Security128bit );
718 if( mbEncrypt && aPermissionPassword.getLength() && ! aPreparedPermissionPassword.getLength() )
719 aPreparedPermissionPassword = comphelper::OStorageHelper::CreatePackageEncryptionData( aPermissionPassword );
721 // after this point we don't need the legacy clear passwords anymore
722 // however they are still inside the passed filter data sequence
723 // which is sadly out out our control
724 aPermissionPassword = rtl::OUString();
725 aOpenPassword = rtl::OUString();
728 * FIXME: the entries are only implicitly defined by the resource file. Should there
729 * ever be an additional form submit format this could get invalid.
731 switch( mnFormsFormat )
733 case 1:
734 aContext.SubmitFormat = PDFWriter::PDF;
735 break;
736 case 2:
737 aContext.SubmitFormat = PDFWriter::HTML;
738 break;
739 case 3:
740 aContext.SubmitFormat = PDFWriter::XML;
741 break;
742 default:
743 case 0:
744 aContext.SubmitFormat = PDFWriter::FDF;
745 break;
747 aContext.AllowDuplicateFieldNames = mbAllowDuplicateFieldNames;
749 //get model
750 Reference< frame::XModel > xModel( mxSrcDoc, UNO_QUERY );
752 //---> i56629 Relative link stuff
753 //set the base URL of the file:
754 //then base URL
755 aContext.BaseURL = xModel->getURL();
756 //relative link option is private to PDF Export filter and limited to local filesystem only
757 aContext.RelFsys = mbExportRelativeFsysLinks;
758 //determine the default acton for PDF links
759 switch( mnDefaultLinkAction )
761 default:
762 //default: URI, without fragment conversion (the bookmark in PDF may not work)
763 case 0:
764 aContext.DefaultLinkAction = PDFWriter::URIAction;
765 break;
766 //view PDF through the reader application
767 case 1:
768 aContext.ForcePDFAction = sal_True;
769 aContext.DefaultLinkAction = PDFWriter::LaunchAction;
770 break;
771 //view PDF through an Internet browser
772 case 2:
773 aContext.DefaultLinkAction = PDFWriter::URIActionDestination;
774 break;
776 aContext.ConvertOOoTargetToPDFTarget = mbConvertOOoTargetToPDFTarget;
777 // check for Link Launch action, not allowed on PDF/A-1
778 // this code chunk checks when the filter is called from scripting
779 if( aContext.Version == PDFWriter::PDF_A_1 &&
780 aContext.DefaultLinkAction == PDFWriter::LaunchAction )
781 { //force the similar allowed URI action
782 aContext.DefaultLinkAction = PDFWriter::URIActionDestination;
783 //and remove the remote goto action forced on PDF file
784 aContext.ForcePDFAction = sal_False;
786 //<---
788 // all context data set, time to create the printing device
789 PDFWriter* pPDFWriter = new PDFWriter( aContext, xEnc );
790 OutputDevice* pOut = pPDFWriter->GetReferenceDevice();
791 vcl::PDFExtOutDevData* pPDFExtOutDevData = NULL;
793 DBG_ASSERT( pOut, "PDFExport::Export: no reference device" );
794 pXDevice->SetOutputDevice( pOut );
796 if( mbAddStream )
798 // export stream
799 // get mimetype
800 OUString aSrcMimetype = getMimetypeForDocument( mxMSF, mxSrcDoc );
801 pPDFWriter->AddStream( aSrcMimetype,
802 new PDFExportStreamDoc( mxSrcDoc, aPreparedPermissionPassword ),
803 false
807 if ( pOut )
809 DBG_ASSERT( pOut->GetExtOutDevData() == NULL, "PDFExport: ExtOutDevData already set!!!" );
810 pPDFExtOutDevData = new vcl::PDFExtOutDevData( *pOut );
811 pOut->SetExtOutDevData( pPDFExtOutDevData );
812 pPDFExtOutDevData->SetIsExportNotes( mbExportNotes );
813 pPDFExtOutDevData->SetIsExportTaggedPDF( mbUseTaggedPDF );
814 pPDFExtOutDevData->SetIsExportTransitionEffects( mbUseTransitionEffects );
815 pPDFExtOutDevData->SetFormsFormat( mnFormsFormat );
816 pPDFExtOutDevData->SetIsExportFormFields( mbExportFormFields );
817 pPDFExtOutDevData->SetIsExportBookmarks( mbExportBookmarks );
818 pPDFExtOutDevData->SetIsLosslessCompression( mbUseLosslessCompression );
819 pPDFExtOutDevData->SetIsReduceImageResolution( mbReduceImageResolution );
820 pPDFExtOutDevData->SetIsExportNamedDestinations( mbExportBmkToDest );
822 Sequence< PropertyValue > aRenderOptions( 6 );
823 aRenderOptions[ 0 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "RenderDevice" ) );
824 aRenderOptions[ 0 ].Value <<= Reference< awt::XDevice >( pXDevice );
825 aRenderOptions[ 1 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotesPages" ) );
826 aRenderOptions[ 1 ].Value <<= sal_False;
827 Any& rExportNotesValue = aRenderOptions[ 1 ].Value;
828 aRenderOptions[ 2 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) );
829 aRenderOptions[ 2 ].Value <<= sal_True;
830 aRenderOptions[ 3 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) );
831 aRenderOptions[ 3 ].Value <<= sal_False;
832 aRenderOptions[ 4 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSkipEmptyPages" ) );
833 aRenderOptions[ 4 ].Value <<= mbSkipEmptyPages;
834 aRenderOptions[ 5 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) );
835 aRenderOptions[ 5 ].Value <<= aPageRange;
837 if( aPageRange.getLength() || !aSelection.hasValue() )
839 aSelection = Any();
840 aSelection <<= mxSrcDoc;
842 sal_Bool bSecondPassForImpressNotes = sal_False;
843 bool bReChangeToNormalView = false;
844 ::rtl::OUString sShowOnlineLayout( RTL_CONSTASCII_USTRINGPARAM( "ShowOnlineLayout"));
845 uno::Reference< beans::XPropertySet > xViewProperties;
847 if ( aCreator.EqualsAscii( "Writer" ) )
849 //i92835 if Writer is in web layout mode this has to be switched to normal view and back to web view in the end
852 Reference< view::XViewSettingsSupplier > xVSettingsSupplier( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
853 xViewProperties = xVSettingsSupplier->getViewSettings();
854 xViewProperties->getPropertyValue( sShowOnlineLayout ) >>= bReChangeToNormalView;
855 if( bReChangeToNormalView )
857 xViewProperties->setPropertyValue( sShowOnlineLayout, uno::makeAny( false ) );
860 catch( const uno::Exception& )
866 const sal_Int32 nPageCount = xRenderable->getRendererCount( aSelection, aRenderOptions );
867 const Range aRange( 1, nPageCount );
868 MultiSelection aMultiSelection;
870 if ( mbExportNotesPages && aCreator.EqualsAscii( "Impress" ) )
872 uno::Reference< drawing::XShapes > xShapes; // sj: do not allow to export notes when
873 if ( ! ( aSelection >>= xShapes ) ) // exporting a selection -> todo: in the dialog
874 bSecondPassForImpressNotes = sal_True; // the export notes checkbox needs to be disabled
877 if( !aPageRange.getLength() )
879 aMultiSelection.SetTotalRange( aRange );
880 aMultiSelection.Select( aRange );
882 else
884 aMultiSelection = MultiSelection( aPageRange );
885 aMultiSelection.SetTotalRange( aRange );
887 if ( mxStatusIndicator.is() )
889 ByteString aResMgrName( "pdffilter" );
890 ResMgr* pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
891 if ( pResMgr )
893 sal_Int32 nTotalPageCount = aMultiSelection.GetSelectCount();
894 if ( bSecondPassForImpressNotes )
895 nTotalPageCount *= 2;
896 mxStatusIndicator->start( String( ResId( PDF_PROGRESS_BAR, *pResMgr ) ), nTotalPageCount );
897 delete pResMgr;
901 if( nPageCount > 0 )
902 bRet = ExportSelection( *pPDFWriter, xRenderable, aSelection, aMultiSelection, aRenderOptions, nPageCount );
903 else
904 bRet = sal_False;
906 if ( bRet && bSecondPassForImpressNotes )
908 rExportNotesValue <<= sal_True;
909 bRet = ExportSelection( *pPDFWriter, xRenderable, aSelection, aMultiSelection, aRenderOptions, nPageCount );
911 if ( mxStatusIndicator.is() )
912 mxStatusIndicator->end();
914 // if during the export the doc locale was set copy it to PDF writer
915 const com::sun::star::lang::Locale& rLoc( pPDFExtOutDevData->GetDocumentLocale() );
916 if( rLoc.Language.getLength() )
917 pPDFWriter->SetDocumentLocale( rLoc );
919 if( bRet )
921 pPDFExtOutDevData->PlayGlobalActions( *pPDFWriter );
922 pPDFWriter->Emit();
923 aErrors = pPDFWriter->GetErrors();
925 pOut->SetExtOutDevData( NULL );
926 if( bReChangeToNormalView )
930 xViewProperties->setPropertyValue( sShowOnlineLayout, uno::makeAny( true ) );
932 catch( const uno::Exception& )
938 delete pPDFExtOutDevData;
939 delete pPDFWriter;
943 // show eventual errors during export
944 showErrors( aErrors );
946 return bRet;
949 namespace
952 typedef cppu::WeakComponentImplHelper1< task::XInteractionRequest > PDFErrorRequestBase;
954 class PDFErrorRequest : private cppu::BaseMutex,
955 public PDFErrorRequestBase
957 task::PDFExportException maExc;
958 public:
959 PDFErrorRequest( const task::PDFExportException& i_rExc );
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);
966 PDFErrorRequest::PDFErrorRequest( const task::PDFExportException& i_rExc ) :
967 PDFErrorRequestBase( m_aMutex ),
968 maExc( i_rExc )
972 uno::Any SAL_CALL PDFErrorRequest::getRequest() throw (uno::RuntimeException)
974 osl::MutexGuard const guard( m_aMutex );
976 uno::Any aRet;
977 aRet <<= maExc;
978 return aRet;
981 uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL PDFErrorRequest::getContinuations() throw (uno::RuntimeException)
983 return uno::Sequence< uno::Reference< task::XInteractionContinuation > >();
986 } // namespace
988 void PDFExport::showErrors( const std::set< PDFWriter::ErrorCode >& rErrors )
990 if( ! rErrors.empty() && mxIH.is() )
992 task::PDFExportException aExc;
993 aExc.ErrorCodes.realloc( sal_Int32(rErrors.size()) );
994 sal_Int32 i = 0;
995 for( std::set< PDFWriter::ErrorCode >::const_iterator it = rErrors.begin();
996 it != rErrors.end(); ++it, i++ )
998 aExc.ErrorCodes.getArray()[i] = (sal_Int32)*it;
1000 Reference< task::XInteractionRequest > xReq( new PDFErrorRequest( aExc ) );
1001 mxIH->handle( xReq );
1005 // -----------------------------------------------------------------------------
1007 sal_Bool PDFExport::ImplExportPage( PDFWriter& rWriter, PDFExtOutDevData& rPDFExtOutDevData, const GDIMetaFile& rMtf )
1009 const Size aSizePDF( OutputDevice::LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_POINT ) );
1010 Point aOrigin;
1011 Rectangle aPageRect( aOrigin, rMtf.GetPrefSize() );
1012 sal_Bool bRet = sal_True;
1014 rWriter.NewPage( aSizePDF.Width(), aSizePDF.Height() );
1015 rWriter.SetMapMode( rMtf.GetPrefMapMode() );
1017 vcl::PDFWriter::PlayMetafileContext aCtx;
1018 GDIMetaFile aMtf;
1019 if( mbRemoveTransparencies )
1021 aCtx.m_bTransparenciesWereRemoved = rWriter.GetReferenceDevice()->
1022 RemoveTransparenciesFromMetaFile( rMtf, aMtf, mnMaxImageResolution, mnMaxImageResolution,
1023 false, true, mbReduceImageResolution );
1025 else
1027 aMtf = rMtf;
1029 aCtx.m_nMaxImageResolution = mbReduceImageResolution ? mnMaxImageResolution : 0;
1030 aCtx.m_bOnlyLosslessCompression = mbUseLosslessCompression;
1031 aCtx.m_nJPEGQuality = mnQuality;
1034 basegfx::B2DRectangle aB2DRect( aPageRect.Left(), aPageRect.Top(), aPageRect.Right(), aPageRect.Bottom() );
1035 rWriter.SetClipRegion( basegfx::B2DPolyPolygon( basegfx::tools::createPolygonFromRect( aB2DRect ) ) );
1037 rWriter.PlayMetafile( aMtf, aCtx, &rPDFExtOutDevData );
1039 rPDFExtOutDevData.ResetSyncData();
1041 if( mbWatermark )
1042 ImplWriteWatermark( rWriter, aSizePDF );
1044 return bRet;
1047 // -----------------------------------------------------------------------------
1049 void PDFExport::ImplWriteWatermark( PDFWriter& rWriter, const Size& rPageSize )
1051 OUString aText( RTL_CONSTASCII_USTRINGPARAM( "Watermark" ) );
1052 Font aFont( OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica" ) ), Size( 0, 3*rPageSize.Height()/4 ) );
1053 aFont.SetItalic( ITALIC_NONE );
1054 aFont.SetWidthType( WIDTH_NORMAL );
1055 aFont.SetWeight( WEIGHT_NORMAL );
1056 aFont.SetAlign( ALIGN_BOTTOM );
1057 long nTextWidth = rPageSize.Width();
1058 if( rPageSize.Width() < rPageSize.Height() )
1060 nTextWidth = rPageSize.Height();
1061 aFont.SetOrientation( 2700 );
1064 if( ! ( maWatermark >>= aText ) )
1066 // more complicated watermark ?
1069 // adjust font height for text to fit
1070 OutputDevice* pDev = rWriter.GetReferenceDevice();
1071 pDev->Push( PUSH_ALL );
1072 pDev->SetFont( aFont );
1073 pDev->SetMapMode( MapMode( MAP_POINT ) );
1074 int w = 0;
1075 while( ( w = pDev->GetTextWidth( aText ) ) > nTextWidth )
1077 long nNewHeight = aFont.GetHeight() * nTextWidth / w;
1078 if( nNewHeight == aFont.GetHeight() )
1080 nNewHeight--;
1081 if( nNewHeight <= 0 )
1082 break;
1084 aFont.SetHeight( nNewHeight );
1085 pDev->SetFont( aFont );
1087 long nTextHeight = pDev->GetTextHeight();
1088 // leave some maneuvering room for rounding issues, also
1089 // some fonts go a little outside ascent/descent
1090 nTextHeight += nTextHeight/20;
1091 pDev->Pop();
1093 rWriter.Push( PUSH_ALL );
1094 rWriter.SetMapMode( MapMode( MAP_POINT ) );
1095 rWriter.SetFont( aFont );
1096 rWriter.SetTextColor( COL_RED );
1097 Point aTextPoint;
1098 Rectangle aTextRect;
1099 if( rPageSize.Width() > rPageSize.Height() )
1101 aTextPoint = Point( (rPageSize.Width()-w)/2,
1102 rPageSize.Height()-(rPageSize.Height()-nTextHeight)/2 );
1103 aTextRect = Rectangle( Point( (rPageSize.Width()-w)/2,
1104 (rPageSize.Height()-nTextHeight)/2 ),
1105 Size( w, nTextHeight ) );
1107 else
1109 aTextPoint = Point( (rPageSize.Width()-nTextHeight)/2,
1110 (rPageSize.Height()-w)/2 );
1111 aTextRect = Rectangle( aTextPoint, Size( nTextHeight, w ) );
1113 rWriter.SetClipRegion();
1114 rWriter.BeginTransparencyGroup();
1115 rWriter.DrawText( aTextPoint, aText );
1116 rWriter.EndTransparencyGroup( aTextRect, 50 );
1117 rWriter.Pop();