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