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"
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
;
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
),
107 mxStatusIndicator ( rxStatusIndicator
),
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 ),
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 ),
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 ),
155 mbExportRelativeFsysLinks ( sal_False
),
156 mnDefaultLinkAction ( 0 ),
157 mbConvertOOoTargetToPDFTarget( sal_False
),
158 mbExportBmkToDest ( sal_False
)
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();
192 vcl::PDFExtOutDevData
* pPDFExtOutDevData
= PTR_CAST( vcl::PDFExtOutDevData
, pOut
->GetExtOutDevData() );
195 sal_Int32 nSel
= aMultiSelection
.FirstSelected();
196 while ( nSel
!= sal_Int32(SFX_ENDOFSELECTION
) )
198 Sequence
< PropertyValue
> aRenderer( rRenderable
->getRenderer( nSel
- 1, rSelection
, rRenderOptions
) );
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 );
210 const MapMode
aMapMode( MAP_100TH_MM
);
211 const Size
aMtfSize( aPageSize
.Width
, aPageSize
.Height
);
214 pOut
->EnableOutput( sal_False
);
215 pOut
->SetMapMode( aMapMode
);
217 aMtf
.SetPrefSize( aMtfSize
);
218 aMtf
.SetPrefMapMode( aMapMode
);
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
;
229 rRenderable
->render( nCurrentRenderer
, rSelection
, rRenderOptions
);
234 if( aMtf
.GetActionCount() &&
235 ( !mbSkipEmptyPages
|| aPageSize
.Width
|| aPageSize
.Height
) )
236 bRet
= ImplExportPage( rPDFWriter
, *pPDFExtOutDevData
, aMtf
) || bRet
;
240 if ( mxStatusIndicator
.is() )
241 mxStatusIndicator
->setValue( mnProgressValue
);
243 *pFirstPage
<<= sal_False
;
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
)
262 class PDFExportStreamDoc
: public vcl::PDFOutputStream
264 Reference
< XComponent
> m_xSrcDoc
;
265 Sequence
< beans::NamedValue
> m_aPreparedPassword
;
267 PDFExportStreamDoc( const Reference
< XComponent
>& xDoc
, const Sequence
<beans::NamedValue
>& rPwd
)
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
);
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" ) ),
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" ) ) ),
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" ) ) ),
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" ) ),
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
349 Reference
< container::XNameAccess
> xFilterFactory(
350 xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
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" ) ),
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
;
380 sal_Bool
PDFExport::Export( const OUString
& rFile
, const Sequence
< PropertyValue
>& rFilterData
)
382 INetURLObject
aURL( rFile
);
384 sal_Bool bRet
= sal_False
;
386 std::set
< PDFWriter::ErrorCode
> aErrors
;
388 if( aURL
.GetProtocol() != INET_PROT_FILE
)
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
;
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
413 Reference
< XServiceInfo
> xInfo( mxSrcDoc
, UNO_QUERY
);
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
442 ::utl::ConfigManager
* pMgr
= ::utl::ConfigManager::GetConfigManager();
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
;
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
;
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
)
568 aContext
.Version
= PDFWriter::PDF_1_4
;
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
;
581 mbEncrypt
= sal_False
;
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
)
605 aContext
.PDFDocumentMode
= PDFWriter::ModeDefault
;
608 aContext
.PDFDocumentMode
= PDFWriter::UseOutlines
;
611 aContext
.PDFDocumentMode
= PDFWriter::UseThumbs
;
614 switch( mnPDFDocumentAction
)
618 aContext
.PDFDocumentAction
= PDFWriter::ActionDefault
;
621 aContext
.PDFDocumentAction
= PDFWriter::FitInWindow
;
624 aContext
.PDFDocumentAction
= PDFWriter::FitWidth
;
627 aContext
.PDFDocumentAction
= PDFWriter::FitVisible
;
630 aContext
.PDFDocumentAction
= PDFWriter::ActionZoom
;
631 aContext
.Zoom
= mnZoom
;
635 switch( mnPDFPageLayout
)
639 aContext
.PageLayout
= PDFWriter::DefaultLayout
;
642 aContext
.PageLayout
= PDFWriter::SinglePage
;
645 aContext
.PageLayout
= PDFWriter::Continuous
;
648 aContext
.PageLayout
= PDFWriter::ContinuousFacing
;
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
673 //force permission to default
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
686 aContext
.Encryption
.CanPrintFull
= sal_True
;
688 aContext
.Encryption
.CanPrintTheDocument
= sal_True
;
692 switch( mnChangesAllowed
)
694 case 0: //already in struct PDFSecPermissions CTOR
697 aContext
.Encryption
.CanAssemble
= sal_True
;
700 aContext
.Encryption
.CanFillInteractive
= sal_True
;
703 aContext
.Encryption
.CanAddOrModify
= sal_True
;
707 aContext
.Encryption
.CanModifyTheContent
=
708 aContext
.Encryption
.CanCopyOrExtract
=
709 aContext
.Encryption
.CanAddOrModify
=
710 aContext
.Encryption
.CanFillInteractive
= sal_True
;
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
)
734 aContext
.SubmitFormat
= PDFWriter::PDF
;
737 aContext
.SubmitFormat
= PDFWriter::HTML
;
740 aContext
.SubmitFormat
= PDFWriter::XML
;
744 aContext
.SubmitFormat
= PDFWriter::FDF
;
747 aContext
.AllowDuplicateFieldNames
= mbAllowDuplicateFieldNames
;
750 Reference
< frame::XModel
> xModel( mxSrcDoc
, UNO_QUERY
);
752 //---> i56629 Relative link stuff
753 //set the base URL of the file:
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
)
762 //default: URI, without fragment conversion (the bookmark in PDF may not work)
764 aContext
.DefaultLinkAction
= PDFWriter::URIAction
;
766 //view PDF through the reader application
768 aContext
.ForcePDFAction
= sal_True
;
769 aContext
.DefaultLinkAction
= PDFWriter::LaunchAction
;
771 //view PDF through an Internet browser
773 aContext
.DefaultLinkAction
= PDFWriter::URIActionDestination
;
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
;
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
);
800 OUString aSrcMimetype
= getMimetypeForDocument( mxMSF
, mxSrcDoc
);
801 pPDFWriter
->AddStream( aSrcMimetype
,
802 new PDFExportStreamDoc( mxSrcDoc
, aPreparedPermissionPassword
),
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() )
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
);
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() );
893 sal_Int32 nTotalPageCount
= aMultiSelection
.GetSelectCount();
894 if ( bSecondPassForImpressNotes
)
895 nTotalPageCount
*= 2;
896 mxStatusIndicator
->start( String( ResId( PDF_PROGRESS_BAR
, *pResMgr
) ), nTotalPageCount
);
902 bRet
= ExportSelection( *pPDFWriter
, xRenderable
, aSelection
, aMultiSelection
, aRenderOptions
, nPageCount
);
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
);
921 pPDFExtOutDevData
->PlayGlobalActions( *pPDFWriter
);
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
;
943 // show eventual errors during export
944 showErrors( aErrors
);
952 typedef cppu::WeakComponentImplHelper1
< task::XInteractionRequest
> PDFErrorRequestBase
;
954 class PDFErrorRequest
: private cppu::BaseMutex
,
955 public PDFErrorRequestBase
957 task::PDFExportException maExc
;
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
),
972 uno::Any SAL_CALL
PDFErrorRequest::getRequest() throw (uno::RuntimeException
)
974 osl::MutexGuard
const guard( m_aMutex
);
981 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > SAL_CALL
PDFErrorRequest::getContinuations() throw (uno::RuntimeException
)
983 return uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> >();
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()) );
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
) );
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
;
1019 if( mbRemoveTransparencies
)
1021 aCtx
.m_bTransparenciesWereRemoved
= rWriter
.GetReferenceDevice()->
1022 RemoveTransparenciesFromMetaFile( rMtf
, aMtf
, mnMaxImageResolution
, mnMaxImageResolution
,
1023 false, true, mbReduceImageResolution
);
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();
1042 ImplWriteWatermark( rWriter
, aSizePDF
);
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
) );
1075 while( ( w
= pDev
->GetTextWidth( aText
) ) > nTextWidth
)
1077 long nNewHeight
= aFont
.GetHeight() * nTextWidth
/ w
;
1078 if( nNewHeight
== aFont
.GetHeight() )
1081 if( nNewHeight
<= 0 )
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;
1093 rWriter
.Push( PUSH_ALL
);
1094 rWriter
.SetMapMode( MapMode( MAP_POINT
) );
1095 rWriter
.SetFont( aFont
);
1096 rWriter
.SetTextColor( COL_RED
);
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
) );
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 );