1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pdfexport.cxx,v $
10 * $Revision: 1.69.36.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_filter.hxx"
34 #include "pdfexport.hxx"
35 #include "impdialog.hxx"
38 #include <tools/urlobj.hxx>
39 #include <tools/fract.hxx>
40 #include <tools/poly.hxx>
41 #include <vcl/mapmod.hxx>
42 #include <vcl/virdev.hxx>
43 #include <vcl/metaact.hxx>
44 #include <vcl/gdimtf.hxx>
45 #include <vcl/jobset.hxx>
46 #include <vcl/salbtype.hxx>
47 #include <vcl/bmpacc.hxx>
48 #include "vcl/svapp.hxx"
49 #include <toolkit/awt/vclxdevice.hxx>
50 #include <unotools/localfilehelper.hxx>
51 #include <unotools/processfactory.hxx>
52 #include <svtools/FilterConfigItem.hxx>
53 #include <svtools/filter.hxx>
54 #include <svtools/solar.hrc>
55 #include <comphelper/string.hxx>
57 #include <svtools/saveopt.hxx> // only for testing of relative saving options in PDF
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 <unotools/configmgr.hxx>
73 #include <com/sun/star/lang/XServiceInfo.hpp>
74 #include <com/sun/star/drawing/XShapes.hpp>
76 using namespace ::rtl
;
77 using namespace ::vcl
;
78 using namespace ::com::sun::star
;
79 using namespace ::com::sun::star::uno
;
80 using namespace ::com::sun::star::lang
;
81 using namespace ::com::sun::star::beans
;
82 using namespace ::com::sun::star::view
;
84 sal_Bool
GetPropertyValue( Any
& rAny
, const Reference
< XPropertySet
> & rXPropSet
, const sal_Char
* pName
)
86 sal_Bool bRetValue
= sal_True
;
89 rAny
= rXPropSet
->getPropertyValue( String::CreateFromAscii( pName
) );
90 if ( !rAny
.hasValue() )
91 bRetValue
= sal_False
;
93 catch( ::com::sun::star::uno::Exception
& )
95 bRetValue
= sal_False
;
100 OUString
GetProperty( const Reference
< XPropertySet
> & rXPropSet
, const sal_Char
* pName
)
104 if ( GetPropertyValue( aAny
, rXPropSet
, pName
) )
113 PDFExport::PDFExport( const Reference
< XComponent
>& rxSrcDoc
, Reference
< task::XStatusIndicator
>& rxStatusIndicator
, const Reference
< lang::XMultiServiceFactory
>& xFactory
) :
114 mxSrcDoc ( rxSrcDoc
),
116 mxStatusIndicator ( rxStatusIndicator
),
117 mbUseTaggedPDF ( sal_False
),
118 mnPDFTypeSelection ( 0 ),
119 mbExportNotes ( sal_True
),
120 mbExportNotesPages ( sal_False
),
121 mbEmbedStandardFonts ( sal_False
),//in preparation for i54636 and i76458.
122 //already used for i59651 (PDF/A-1)
123 mbUseTransitionEffects ( sal_True
),
124 mbExportBookmarks ( sal_True
),
125 mnOpenBookmarkLevels ( -1 ),
126 mbUseLosslessCompression ( sal_False
),
127 mbReduceImageResolution ( sal_False
),
128 mbSkipEmptyPages ( sal_True
),
129 mbAddStream ( sal_False
),
130 mnMaxImageResolution ( 300 ),
133 mbExportFormFields ( sal_True
),
134 mnProgressValue ( 0 ),
135 mbRemoveTransparencies ( sal_False
),
136 mbWatermark ( sal_False
),
138 mbHideViewerToolbar ( sal_False
),
139 mbHideViewerMenubar ( sal_False
),
140 mbHideViewerWindowControls ( sal_False
),
141 mbFitWindow ( sal_False
),
142 mbCenterWindow ( sal_False
),
143 mbOpenInFullScreenMode ( sal_False
),
144 mbDisplayPDFDocumentTitle ( sal_True
),
145 mnPDFDocumentMode ( 0 ),
146 mnPDFDocumentAction ( 0 ),
149 mnPDFPageLayout ( 0 ),
150 mbFirstPageLeft ( sal_False
),
152 mbEncrypt ( sal_False
),
154 mbRestrictPermissions ( sal_False
),
155 msPermissionPassword (),
156 mnPrintAllowed ( 2 ),
157 mnChangesAllowed ( 4 ),
158 mbCanCopyOrExtract ( sal_True
),
159 mbCanExtractForAccessibility( sal_True
),
161 mnCachePatternId ( -1 ),
164 mbExportRelativeFsysLinks ( sal_False
),
165 mnDefaultLinkAction ( 0 ),
166 mbConvertOOoTargetToPDFTarget( sal_False
),
167 mbExportBmkToDest ( sal_False
)
172 // -----------------------------------------------------------------------------
174 PDFExport::~PDFExport()
178 // -----------------------------------------------------------------------------
180 sal_Bool
PDFExport::ExportSelection( vcl::PDFWriter
& rPDFWriter
, Reference
< com::sun::star::view::XRenderable
>& rRenderable
, Any
& rSelection
,
181 MultiSelection aMultiSelection
, Sequence
< PropertyValue
>& rRenderOptions
, sal_Int32 nPageCount
)
183 sal_Bool bRet
= sal_False
;
186 Any
* pFirstPage
= NULL
;
187 Any
* pLastPage
= NULL
;
189 for( sal_Int32 nData
= 0, nDataCount
= rRenderOptions
.getLength(); nData
< nDataCount
; ++nData
)
191 if( rRenderOptions
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) ) )
192 pFirstPage
= &rRenderOptions
[ nData
].Value
;
193 else if( rRenderOptions
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) ) )
194 pLastPage
= &rRenderOptions
[ nData
].Value
;
197 OutputDevice
* pOut
= rPDFWriter
.GetReferenceDevice();
201 vcl::PDFExtOutDevData
* pPDFExtOutDevData
= PTR_CAST( vcl::PDFExtOutDevData
, pOut
->GetExtOutDevData() );
204 sal_Int32 nSel
= aMultiSelection
.FirstSelected();
205 while ( nSel
!= sal_Int32(SFX_ENDOFSELECTION
) )
207 Sequence
< PropertyValue
> aRenderer( rRenderable
->getRenderer( nSel
- 1, rSelection
, rRenderOptions
) );
210 for( sal_Int32 nProperty
= 0, nPropertyCount
= aRenderer
.getLength(); nProperty
< nPropertyCount
; ++nProperty
)
212 if( aRenderer
[ nProperty
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) )
213 aRenderer
[ nProperty
].Value
>>= aPageSize
;
216 pPDFExtOutDevData
->SetCurrentPageNumber( nSel
- 1 );
219 const MapMode
aMapMode( MAP_100TH_MM
);
220 const Size
aMtfSize( aPageSize
.Width
, aPageSize
.Height
);
223 pOut
->EnableOutput( FALSE
);
224 pOut
->SetMapMode( aMapMode
);
226 aMtf
.SetPrefSize( aMtfSize
);
227 aMtf
.SetPrefMapMode( aMapMode
);
230 // --> FME 2004-10-08 #i35176#
231 // IsLastPage property.
232 const sal_Int32 nCurrentRenderer
= nSel
- 1;
233 nSel
= aMultiSelection
.NextSelected();
234 if ( pLastPage
&& sal_Int32(SFX_ENDOFSELECTION
) == nSel
)
235 *pLastPage
<<= sal_True
;
238 rRenderable
->render( nCurrentRenderer
, rSelection
, rRenderOptions
);
243 if( aMtf
.GetActionCount() &&
244 ( !mbSkipEmptyPages
|| aPageSize
.Width
|| aPageSize
.Height
) )
245 bRet
= ImplExportPage( rPDFWriter
, *pPDFExtOutDevData
, aMtf
) || bRet
;
249 if ( mxStatusIndicator
.is() )
250 mxStatusIndicator
->setValue( mnProgressValue
);
252 *pFirstPage
<<= sal_False
;
259 bRet
= sal_True
; // #i18334# SJ: nPageCount == 0,
260 rPDFWriter
.NewPage( 10000, 10000 ); // creating dummy page
261 rPDFWriter
.SetMapMode( MAP_100TH_MM
); //
265 catch( RuntimeException
)
271 class PDFExportStreamDoc
: public vcl::PDFOutputStream
273 Reference
< XComponent
> m_xSrcDoc
;
274 rtl::OUString m_aPassWd
;
276 PDFExportStreamDoc( const Reference
< XComponent
>& xDoc
, const rtl::OUString
& rPwd
)
280 virtual ~PDFExportStreamDoc();
282 virtual void write( const Reference
< XOutputStream
>& xStream
);
285 PDFExportStreamDoc::~PDFExportStreamDoc()
289 void PDFExportStreamDoc::write( const Reference
< XOutputStream
>& xStream
)
291 Reference
< com::sun::star::frame::XStorable
> xStore( m_xSrcDoc
, UNO_QUERY
);
294 Sequence
< beans::PropertyValue
> aArgs( m_aPassWd
.getLength() ? 3 : 2 );
295 aArgs
.getArray()[0].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
296 aArgs
.getArray()[1].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) );
297 aArgs
.getArray()[1].Value
<<= xStream
;
298 if( m_aPassWd
.getLength() )
300 aArgs
.getArray()[2].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) );
301 aArgs
.getArray()[2].Value
<<= m_aPassWd
;
305 xStore
->storeToURL( OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ),
308 catch( IOException
& )
314 static OUString
getMimetypeForDocument( const Reference
< XMultiServiceFactory
>& xFactory
,
315 const Reference
< XComponent
>& xDoc
) throw()
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" ) ) ),
323 if( xModuleManager
.is() && xStore
.is() )
325 OUString aDocServiceName
= xModuleManager
->identify( Reference
< XInterface
>( xStore
, uno::UNO_QUERY
) );
326 if ( aDocServiceName
.getLength() )
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" ) ) ),
334 if( xConfigProvider
.is() )
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
;
342 Reference
< container::XNameAccess
> xSOFConfig(
343 xConfigProvider
->createInstanceWithArguments(
344 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) ),
348 Reference
< container::XNameAccess
> xApplConfig
;
349 xSOFConfig
->getByName( aDocServiceName
) >>= xApplConfig
;
350 if ( xApplConfig
.is() )
352 xApplConfig
->getByName( OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupFactoryActualFilter" ) ) ) >>= aFilterName
;
353 if( aFilterName
.getLength() )
355 // find the related type name
357 Reference
< container::XNameAccess
> xFilterFactory(
358 xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
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
;
367 if ( aTypeName
.getLength() )
369 // find the mediatype
370 Reference
< container::XNameAccess
> xTypeDetection(
371 xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
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
;
388 sal_Bool
PDFExport::Export( const OUString
& rFile
, const Sequence
< PropertyValue
>& rFilterData
)
390 INetURLObject
aURL( rFile
);
392 sal_Bool bRet
= sal_False
;
394 std::set
< PDFWriter::ErrorCode
> aErrors
;
396 if( aURL
.GetProtocol() != INET_PROT_FILE
)
400 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFile
, aTmp
) )
401 aURL
= INetURLObject(aTmp
);
404 if( aURL
.GetProtocol() == INET_PROT_FILE
)
406 Reference
< XRenderable
> xRenderable( mxSrcDoc
, UNO_QUERY
);
408 if( xRenderable
.is() )
410 VCLXDevice
* pXDevice
= new VCLXDevice
;
414 // getting the string for the creator
416 Reference
< XServiceInfo
> xInfo( mxSrcDoc
, UNO_QUERY
);
419 if ( xInfo
->supportsService( rtl::OUString::createFromAscii( "com.sun.star.presentation.PresentationDocument" ) ) )
420 aCreator
.AppendAscii( "Impress" );
421 else if ( xInfo
->supportsService( rtl::OUString::createFromAscii( "com.sun.star.drawing.DrawingDocument" ) ) )
422 aCreator
.AppendAscii( "Draw" );
423 else if ( xInfo
->supportsService( rtl::OUString::createFromAscii( "com.sun.star.text.TextDocument" ) ) )
424 aCreator
.AppendAscii( "Writer" );
425 else if ( xInfo
->supportsService( rtl::OUString::createFromAscii( "com.sun.star.sheet.SpreadsheetDocument" ) ) )
426 aCreator
.AppendAscii( "Calc" );
427 else if ( xInfo
->supportsService( rtl::OUString::createFromAscii( "com.sun.star.formula.FormulaProperties" ) ) )
428 aCreator
.AppendAscii( "Math" );
431 PDFWriter::PDFWriterContext aContext
;
433 for( sal_Int32 nData
= 0, nDataCount
= rFilterData
.getLength(); nData
< nDataCount
; ++nData
)
435 if( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ) )
436 rFilterData
[ nData
].Value
>>= aPageRange
;
437 else if( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "Selection" ) ) )
438 rFilterData
[ nData
].Value
>>= aSelection
;
439 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "UseLosslessCompression" ) ) )
440 rFilterData
[ nData
].Value
>>= mbUseLosslessCompression
;
441 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "Quality" ) ) )
442 rFilterData
[ nData
].Value
>>= mnQuality
;
443 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "ReduceImageResolution" ) ) )
444 rFilterData
[ nData
].Value
>>= mbReduceImageResolution
;
445 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSkipEmptyPages" ) ) )
446 rFilterData
[ nData
].Value
>>= mbSkipEmptyPages
;
447 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "MaxImageResolution" ) ) )
448 rFilterData
[ nData
].Value
>>= mnMaxImageResolution
;
449 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "UseTaggedPDF" ) ) )
450 rFilterData
[ nData
].Value
>>= mbUseTaggedPDF
;
451 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectPdfVersion" ) ) )
452 rFilterData
[ nData
].Value
>>= mnPDFTypeSelection
;
453 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotes" ) ) )
454 rFilterData
[ nData
].Value
>>= mbExportNotes
;
455 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotesPages" ) ) )
456 rFilterData
[ nData
].Value
>>= mbExportNotesPages
;
457 // else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EmbedStandardFonts" ) ) )
458 // rFilterData[ nData ].Value >>= mbEmbedStandardFonts;
459 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "UseTransitionEffects" ) ) )
460 rFilterData
[ nData
].Value
>>= mbUseTransitionEffects
;
461 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportFormFields" ) ) )
462 rFilterData
[ nData
].Value
>>= mbExportFormFields
;
463 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "FormsType" ) ) )
464 rFilterData
[ nData
].Value
>>= mnFormsFormat
;
466 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerToolbar" ) ) )
467 rFilterData
[ nData
].Value
>>= mbHideViewerToolbar
;
468 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerMenubar" ) ) )
469 rFilterData
[ nData
].Value
>>= mbHideViewerMenubar
;
470 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerWindowControls" ) ) )
471 rFilterData
[ nData
].Value
>>= mbHideViewerWindowControls
;
472 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "ResizeWindowToInitialPage" ) ) )
473 rFilterData
[ nData
].Value
>>= mbFitWindow
;
474 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "CenterWindow" ) ) )
475 rFilterData
[ nData
].Value
>>= mbCenterWindow
;
476 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenInFullScreenMode" ) ) )
477 rFilterData
[ nData
].Value
>>= mbOpenInFullScreenMode
;
478 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "DisplayPDFDocumentTitle" ) ) )
479 rFilterData
[ nData
].Value
>>= mbDisplayPDFDocumentTitle
;
480 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "InitialView" ) ) )
481 rFilterData
[ nData
].Value
>>= mnPDFDocumentMode
;
482 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "Magnification" ) ) )
483 rFilterData
[ nData
].Value
>>= mnPDFDocumentAction
;
484 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "Zoom" ) ) )
485 rFilterData
[ nData
].Value
>>= mnZoom
;
486 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "InitialPage" ) ) )
487 rFilterData
[ nData
].Value
>>= mnInitialPage
;
488 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "PageLayout" ) ) )
489 rFilterData
[ nData
].Value
>>= mnPDFPageLayout
;
490 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "FirstPageOnLeft" ) ) )
491 rFilterData
[ nData
].Value
>>= aContext
.FirstPageLeft
;
492 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "IsAddStream" ) ) )
493 rFilterData
[ nData
].Value
>>= mbAddStream
;
494 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "Watermark" ) ) )
496 maWatermark
= rFilterData
[ nData
].Value
;
497 mbWatermark
= sal_True
;
499 //now all the security related properties...
500 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptFile" ) ) )
501 rFilterData
[ nData
].Value
>>= mbEncrypt
;
502 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentOpenPassword" ) ) )
503 rFilterData
[ nData
].Value
>>= msOpenPassword
;
504 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "RestrictPermissions" ) ) )
505 rFilterData
[ nData
].Value
>>= mbRestrictPermissions
;
506 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "PermissionPassword" ) ) )
507 rFilterData
[ nData
].Value
>>= msPermissionPassword
;
508 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "Printing" ) ) )
509 rFilterData
[ nData
].Value
>>= mnPrintAllowed
;
510 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "Changes" ) ) )
511 rFilterData
[ nData
].Value
>>= mnChangesAllowed
;
512 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableCopyingOfContent" ) ) )
513 rFilterData
[ nData
].Value
>>= mbCanCopyOrExtract
;
514 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableTextAccessForAccessibilityTools" ) ) )
515 rFilterData
[ nData
].Value
>>= mbCanExtractForAccessibility
;
516 //--->i56629 links extra (relative links and other related stuff)
517 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportLinksRelativeFsys" ) ) )
518 rFilterData
[ nData
].Value
>>= mbExportRelativeFsysLinks
;
519 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "PDFViewSelection" ) ) )
520 rFilterData
[ nData
].Value
>>= mnDefaultLinkAction
;
521 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "ConvertOOoTargetToPDFTarget" ) ) )
522 rFilterData
[ nData
].Value
>>= mbConvertOOoTargetToPDFTarget
;
523 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarksToPDFDestination" ) ) )
524 rFilterData
[ nData
].Value
>>= mbExportBmkToDest
;
526 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarks" ) ) )
527 rFilterData
[ nData
].Value
>>= mbExportBookmarks
;
528 else if ( rFilterData
[ nData
].Name
== OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenBookmarkLevels" ) ) )
529 rFilterData
[ nData
].Value
>>= mnOpenBookmarkLevels
;
531 aContext
.URL
= aURL
.GetMainURL(INetURLObject::DECODE_TO_IURI
);
533 //set the correct version, depending on user request
534 switch( mnPDFTypeSelection
)
538 aContext
.Version
= PDFWriter::PDF_1_4
;
541 aContext
.Version
= PDFWriter::PDF_A_1
;
542 //force the tagged PDF as well
543 mbUseTaggedPDF
= sal_True
;
544 //force embedding of standard fonts
545 mbEmbedStandardFonts
= sal_True
;
546 //force disabling of form conversion
547 mbExportFormFields
= sal_False
;
548 // PDF/A does not allow transparencies
549 mbRemoveTransparencies
= sal_True
;
553 //copy in context the values default in the contructor or set by the FilterData sequence of properties
554 aContext
.Tagged
= mbUseTaggedPDF
;
556 //values used in viewer
557 aContext
.HideViewerToolbar
= mbHideViewerToolbar
;
558 aContext
.HideViewerMenubar
= mbHideViewerMenubar
;
559 aContext
.HideViewerWindowControls
= mbHideViewerWindowControls
;
560 aContext
.FitWindow
= mbFitWindow
;
561 aContext
.CenterWindow
= mbCenterWindow
;
562 aContext
.OpenInFullScreenMode
= mbOpenInFullScreenMode
;
563 aContext
.DisplayPDFDocumentTitle
= mbDisplayPDFDocumentTitle
;
564 aContext
.InitialPage
= mnInitialPage
-1;
565 aContext
.OpenBookmarkLevels
= mnOpenBookmarkLevels
;
566 aContext
.EmbedStandardFonts
= mbEmbedStandardFonts
;
568 switch( mnPDFDocumentMode
)
572 aContext
.PDFDocumentMode
= PDFWriter::ModeDefault
;
575 aContext
.PDFDocumentMode
= PDFWriter::UseOutlines
;
578 aContext
.PDFDocumentMode
= PDFWriter::UseThumbs
;
581 switch( mnPDFDocumentAction
)
585 aContext
.PDFDocumentAction
= PDFWriter::ActionDefault
;
588 aContext
.PDFDocumentAction
= PDFWriter::FitInWindow
;
591 aContext
.PDFDocumentAction
= PDFWriter::FitWidth
;
594 aContext
.PDFDocumentAction
= PDFWriter::FitVisible
;
597 aContext
.PDFDocumentAction
= PDFWriter::ActionZoom
;
598 aContext
.Zoom
= mnZoom
;
602 switch( mnPDFPageLayout
)
606 aContext
.PageLayout
= PDFWriter::DefaultLayout
;
609 aContext
.PageLayout
= PDFWriter::SinglePage
;
612 aContext
.PageLayout
= PDFWriter::Continuous
;
615 aContext
.PageLayout
= PDFWriter::ContinuousFacing
;
619 aContext
.FirstPageLeft
= mbFirstPageLeft
;
621 //check if PDF/A, which does not allow encryption
622 if( aContext
.Version
!= PDFWriter::PDF_A_1
)
624 //set values needed in encryption
625 aContext
.Encrypt
= mbEncrypt
;
626 //set encryption level, fixed, but here it can set by the UI if needed.
627 // true is 128 bit, false 40
628 //note that in 40 bit mode the UI needs reworking, since the current UI is meaningfull only for
629 //128bit security mode
630 aContext
.Security128bit
= sal_True
;
632 //set the open password
633 if( aContext
.Encrypt
&& msOpenPassword
.getLength() > 0 )
634 aContext
.UserPassword
= msOpenPassword
;
636 //set check for permission change password
637 // if not enabled and no permission password, force permissions to default as if PDF where without encryption
638 if( mbRestrictPermissions
&& msPermissionPassword
.getLength() > 0 )
640 aContext
.OwnerPassword
= msPermissionPassword
;
641 aContext
.Encrypt
= sal_True
;
642 //permission set as desired, done after
646 //force permission to default
648 mnChangesAllowed
= 4 ;
649 mbCanCopyOrExtract
= sal_True
;
650 mbCanExtractForAccessibility
= sal_True
;
653 switch( mnPrintAllowed
)
655 case 0: //initialized when aContext is build, means no printing
659 aContext
.AccessPermissions
.CanPrintFull
= sal_True
;
661 aContext
.AccessPermissions
.CanPrintTheDocument
= sal_True
;
665 switch( mnChangesAllowed
)
667 case 0: //already in struct PDFSecPermissions CTOR
670 aContext
.AccessPermissions
.CanAssemble
= sal_True
;
673 aContext
.AccessPermissions
.CanFillInteractive
= sal_True
;
676 aContext
.AccessPermissions
.CanAddOrModify
= sal_True
;
680 aContext
.AccessPermissions
.CanModifyTheContent
=
681 aContext
.AccessPermissions
.CanCopyOrExtract
=
682 aContext
.AccessPermissions
.CanAddOrModify
=
683 aContext
.AccessPermissions
.CanFillInteractive
= sal_True
;
687 aContext
.AccessPermissions
.CanCopyOrExtract
= mbCanCopyOrExtract
;
688 aContext
.AccessPermissions
.CanExtractForAccessibility
= mbCanExtractForAccessibility
;
691 * FIXME: the entries are only implicitly defined by the resource file. Should there
692 * ever be an additional form submit format this could get invalid.
694 switch( mnFormsFormat
)
697 aContext
.SubmitFormat
= PDFWriter::PDF
;
700 aContext
.SubmitFormat
= PDFWriter::HTML
;
703 aContext
.SubmitFormat
= PDFWriter::XML
;
707 aContext
.SubmitFormat
= PDFWriter::FDF
;
712 Reference
< frame::XModel
> xModel( mxSrcDoc
, UNO_QUERY
);
714 //---> i56629 Relative link stuff
715 //set the base URL of the file:
717 aContext
.BaseURL
= xModel
->getURL();
718 //relative link option is private to PDF Export filter and limited to local filesystem only
719 aContext
.RelFsys
= mbExportRelativeFsysLinks
;
720 //determine the default acton for PDF links
721 switch( mnDefaultLinkAction
)
724 //default: URI, without fragment conversion (the bookmark in PDF may not work)
726 aContext
.DefaultLinkAction
= PDFWriter::URIAction
;
728 //view PDF through the reader application
730 aContext
.ForcePDFAction
= sal_True
;
731 aContext
.DefaultLinkAction
= PDFWriter::LaunchAction
;
733 //view PDF through an Internet browser
735 aContext
.DefaultLinkAction
= PDFWriter::URIActionDestination
;
738 aContext
.ConvertOOoTargetToPDFTarget
= mbConvertOOoTargetToPDFTarget
;
739 // check for Link Launch action, not allowed on PDF/A-1
740 // this code chunk checks when the filter is called from scripting
741 if( aContext
.Version
== PDFWriter::PDF_A_1
&&
742 aContext
.DefaultLinkAction
== PDFWriter::LaunchAction
)
743 { //force the similar allowed URI action
744 aContext
.DefaultLinkAction
= PDFWriter::URIActionDestination
;
745 //and remove the remote goto action forced on PDF file
746 aContext
.ForcePDFAction
= sal_False
;
750 // all context data set, time to create the printing device
751 PDFWriter
* pPDFWriter
= new PDFWriter( aContext
);
752 OutputDevice
* pOut
= pPDFWriter
->GetReferenceDevice();
753 vcl::PDFExtOutDevData
* pPDFExtOutDevData
= NULL
;
755 DBG_ASSERT( pOut
, "PDFExport::Export: no reference device" );
756 pXDevice
->SetOutputDevice( pOut
);
762 OUString aSrcMimetype
= getMimetypeForDocument( mxMSF
, mxSrcDoc
);
763 pPDFWriter
->AddStream( aSrcMimetype
,
764 new PDFExportStreamDoc( mxSrcDoc
, msPermissionPassword
),
769 Reference
< document::XDocumentPropertiesSupplier
> xDocumentPropsSupplier( mxSrcDoc
, UNO_QUERY
);
770 if ( xDocumentPropsSupplier
.is() )
772 Reference
< document::XDocumentProperties
> xDocumentProps( xDocumentPropsSupplier
->getDocumentProperties() );
773 if ( xDocumentProps
.is() )
775 aDocInfo
.Title
= xDocumentProps
->getTitle();
776 aDocInfo
.Author
= xDocumentProps
->getAuthor();
777 aDocInfo
.Subject
= xDocumentProps
->getSubject();
778 aDocInfo
.Keywords
= ::comphelper::string::convertCommaSeparated(xDocumentProps
->getKeywords());
781 // getting the string for the producer
783 ::utl::ConfigManager
* pMgr
= ::utl::ConfigManager::GetConfigManager();
786 Any aProductName
= pMgr
->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME
);
787 ::rtl::OUString sProductName
;
788 aProductName
>>= sProductName
;
789 aProducer
= sProductName
;
790 aProductName
= pMgr
->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION
);
791 aProductName
>>= sProductName
;
792 aProducer
.AppendAscii(" ");
793 aProducer
+= String( sProductName
);
795 aDocInfo
.Producer
= aProducer
;
796 aDocInfo
.Creator
= aCreator
;
798 pPDFWriter
->SetDocInfo( aDocInfo
);
802 DBG_ASSERT( pOut
->GetExtOutDevData() == NULL
, "PDFExport: ExtOutDevData already set!!!" );
803 pPDFExtOutDevData
= new vcl::PDFExtOutDevData( *pOut
);
804 pOut
->SetExtOutDevData( pPDFExtOutDevData
);
805 pPDFExtOutDevData
->SetIsExportNotes( mbExportNotes
);
806 pPDFExtOutDevData
->SetIsExportTaggedPDF( mbUseTaggedPDF
);
807 pPDFExtOutDevData
->SetIsExportTransitionEffects( mbUseTransitionEffects
);
808 pPDFExtOutDevData
->SetFormsFormat( mnFormsFormat
);
809 pPDFExtOutDevData
->SetIsExportFormFields( mbExportFormFields
);
810 pPDFExtOutDevData
->SetIsExportBookmarks( mbExportBookmarks
);
811 pPDFExtOutDevData
->SetIsLosslessCompression( mbUseLosslessCompression
);
812 pPDFExtOutDevData
->SetIsReduceImageResolution( mbReduceImageResolution
);
813 pPDFExtOutDevData
->SetIsExportNamedDestinations( mbExportBmkToDest
);
815 Sequence
< PropertyValue
> aRenderOptions( 6 );
816 aRenderOptions
[ 0 ].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "RenderDevice" ) );
817 aRenderOptions
[ 0 ].Value
<<= Reference
< awt::XDevice
>( pXDevice
);
818 aRenderOptions
[ 1 ].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotesPages" ) );
819 aRenderOptions
[ 1 ].Value
<<= sal_False
;
820 Any
& rExportNotesValue
= aRenderOptions
[ 1 ].Value
;
821 aRenderOptions
[ 2 ].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) );
822 aRenderOptions
[ 2 ].Value
<<= sal_True
;
823 aRenderOptions
[ 3 ].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) );
824 aRenderOptions
[ 3 ].Value
<<= sal_False
;
825 aRenderOptions
[ 4 ].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) );
826 aRenderOptions
[ 4 ].Value
<<= aPageRange
;
827 aRenderOptions
[ 5 ].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSkipEmptyPages" ) );
828 aRenderOptions
[ 5 ].Value
<<= mbSkipEmptyPages
;
830 if( aPageRange
.getLength() || !aSelection
.hasValue() )
833 aSelection
<<= mxSrcDoc
;
835 sal_Bool bSecondPassForImpressNotes
= sal_False
;
836 bool bReChangeToNormalView
= false;
837 ::rtl::OUString
sShowOnlineLayout( RTL_CONSTASCII_USTRINGPARAM( "ShowOnlineLayout"));
838 uno::Reference
< beans::XPropertySet
> xViewProperties
;
840 if ( aCreator
.EqualsAscii( "Writer" ) )
842 //i92835 if Writer is in web layout mode this has to be switched to normal view and back to web view in the end
845 Reference
< view::XViewSettingsSupplier
> xVSettingsSupplier( xModel
->getCurrentController(), uno::UNO_QUERY_THROW
);
846 xViewProperties
= xVSettingsSupplier
->getViewSettings();
847 xViewProperties
->getPropertyValue( sShowOnlineLayout
) >>= bReChangeToNormalView
;
848 if( bReChangeToNormalView
)
850 xViewProperties
->setPropertyValue( sShowOnlineLayout
, uno::makeAny( false ) );
853 catch( const uno::Exception
& )
859 const sal_Int32 nPageCount
= xRenderable
->getRendererCount( aSelection
, aRenderOptions
);
860 const Range
aRange( 1, nPageCount
);
861 MultiSelection aMultiSelection
;
863 if ( mbExportNotesPages
&& aCreator
.EqualsAscii( "Impress" ) )
865 uno::Reference
< drawing::XShapes
> xShapes
; // sj: do not allow to export notes when
866 if ( ! ( aSelection
>>= xShapes
) ) // exporting a selection -> todo: in the dialog
867 bSecondPassForImpressNotes
= sal_True
; // the export notes checkbox needs to be disabled
870 if( !aPageRange
.getLength() )
872 aMultiSelection
.SetTotalRange( aRange
);
873 aMultiSelection
.Select( aRange
);
877 aMultiSelection
= MultiSelection( aPageRange
);
878 aMultiSelection
.SetTotalRange( aRange
);
880 if ( mxStatusIndicator
.is() )
882 ByteString
aResMgrName( "pdffilter" );
883 ResMgr
* pResMgr
= ResMgr::CreateResMgr( aResMgrName
.GetBuffer(), Application::GetSettings().GetUILocale() );
886 sal_Int32 nTotalPageCount
= aMultiSelection
.GetSelectCount();
887 if ( bSecondPassForImpressNotes
)
888 nTotalPageCount
*= 2;
889 mxStatusIndicator
->start( String( ResId( PDF_PROGRESS_BAR
, *pResMgr
) ), nTotalPageCount
);
894 bRet
= ExportSelection( *pPDFWriter
, xRenderable
, aSelection
, aMultiSelection
, aRenderOptions
, nPageCount
);
896 if ( bRet
&& bSecondPassForImpressNotes
)
898 rExportNotesValue
<<= sal_True
;
899 bRet
= ExportSelection( *pPDFWriter
, xRenderable
, aSelection
, aMultiSelection
, aRenderOptions
, nPageCount
);
901 if ( mxStatusIndicator
.is() )
902 mxStatusIndicator
->end();
904 // if during the export the doc locale was set copy it to PDF writer
905 const com::sun::star::lang::Locale
& rLoc( pPDFExtOutDevData
->GetDocumentLocale() );
906 if( rLoc
.Language
.getLength() )
907 pPDFWriter
->SetDocumentLocale( rLoc
);
911 pPDFExtOutDevData
->PlayGlobalActions( *pPDFWriter
);
913 aErrors
= pPDFWriter
->GetErrors();
915 pOut
->SetExtOutDevData( NULL
);
916 if( bReChangeToNormalView
)
920 xViewProperties
->setPropertyValue( sShowOnlineLayout
, uno::makeAny( true ) );
922 catch( const uno::Exception
& )
928 delete pPDFExtOutDevData
;
933 // show eventual errors during export
934 showErrors( aErrors
);
939 void PDFExport::showErrors( const std::set
< PDFWriter::ErrorCode
>& rErrors
)
941 if( ! rErrors
.empty() )
943 ByteString
aResMgrName( "pdffilter" );
944 ResMgr
* pResMgr
= ResMgr::CreateResMgr( aResMgrName
.GetBuffer(), Application::GetSettings().GetUILocale() );
947 ImplErrorDialog
aDlg( rErrors
, *pResMgr
);
954 // -----------------------------------------------------------------------------
956 sal_Bool
PDFExport::ImplExportPage( PDFWriter
& rWriter
, PDFExtOutDevData
& rPDFExtOutDevData
, const GDIMetaFile
& rMtf
)
958 VirtualDevice aDummyVDev
;
959 const Size
aSizePDF( OutputDevice::LogicToLogic( rMtf
.GetPrefSize(), rMtf
.GetPrefMapMode(), MAP_POINT
) );
961 Rectangle
aPageRect( aOrigin
, rMtf
.GetPrefSize() );
962 sal_Bool bRet
= sal_False
;
964 aDummyVDev
.EnableOutput( sal_False
);
965 aDummyVDev
.SetMapMode( rMtf
.GetPrefMapMode() );
967 rWriter
.NewPage( aSizePDF
.Width(), aSizePDF
.Height() );
968 rWriter
.SetMapMode( rMtf
.GetPrefMapMode() );
970 rWriter
.SetClipRegion( aPageRect
);
971 bRet
= ImplWriteActions( rWriter
, &rPDFExtOutDevData
, rMtf
, aDummyVDev
);
972 rPDFExtOutDevData
.ResetSyncData();
975 ImplWriteWatermark( rWriter
, aSizePDF
);
980 // -----------------------------------------------------------------------------
982 void PDFExport::ImplWriteWatermark( PDFWriter
& rWriter
, const Size
& rPageSize
)
984 OUString
aText( RTL_CONSTASCII_USTRINGPARAM( "Watermark" ) );
985 Font
aFont( OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica" ) ), Size( 0, 3*rPageSize
.Height()/4 ) );
986 aFont
.SetItalic( ITALIC_NONE
);
987 aFont
.SetWidthType( WIDTH_NORMAL
);
988 aFont
.SetWeight( WEIGHT_NORMAL
);
989 aFont
.SetAlign( ALIGN_BOTTOM
);
990 long nTextWidth
= rPageSize
.Width();
991 if( rPageSize
.Width() < rPageSize
.Height() )
993 nTextWidth
= rPageSize
.Height();
994 aFont
.SetOrientation( 2700 );
997 if( ! ( maWatermark
>>= aText
) )
999 // more complicated watermark ?
1002 // adjust font height for text to fit
1003 OutputDevice
* pDev
= rWriter
.GetReferenceDevice();
1004 pDev
->Push( PUSH_ALL
);
1005 pDev
->SetFont( aFont
);
1006 pDev
->SetMapMode( MapMode( MAP_POINT
) );
1008 while( ( w
= pDev
->GetTextWidth( aText
) ) > nTextWidth
)
1010 long nNewHeight
= aFont
.GetHeight() * nTextWidth
/ w
;
1011 if( nNewHeight
== aFont
.GetHeight() )
1014 if( nNewHeight
<= 0 )
1017 aFont
.SetHeight( nNewHeight
);
1018 pDev
->SetFont( aFont
);
1020 long nTextHeight
= pDev
->GetTextHeight();
1021 // leave some maneuvering room for rounding issues, also
1022 // some fonts go a little outside ascent/descent
1023 nTextHeight
+= nTextHeight
/20;
1026 rWriter
.Push( PUSH_ALL
);
1027 rWriter
.SetMapMode( MapMode( MAP_POINT
) );
1028 rWriter
.SetFont( aFont
);
1029 rWriter
.SetTextColor( COL_RED
);
1031 Rectangle aTextRect
;
1032 if( rPageSize
.Width() > rPageSize
.Height() )
1034 aTextPoint
= Point( (rPageSize
.Width()-w
)/2,
1035 rPageSize
.Height()-(rPageSize
.Height()-nTextHeight
)/2 );
1036 aTextRect
= Rectangle( Point( (rPageSize
.Width()-w
)/2,
1037 (rPageSize
.Height()-nTextHeight
)/2 ),
1038 Size( w
, nTextHeight
) );
1042 aTextPoint
= Point( (rPageSize
.Width()-nTextHeight
)/2,
1043 (rPageSize
.Height()-w
)/2 );
1044 aTextRect
= Rectangle( aTextPoint
, Size( nTextHeight
, w
) );
1046 rWriter
.SetClipRegion();
1047 rWriter
.BeginTransparencyGroup();
1048 rWriter
.DrawText( aTextPoint
, aText
);
1049 rWriter
.EndTransparencyGroup( aTextRect
, 50 );
1053 // -----------------------------------------------------------------------------
1055 sal_Bool
PDFExport::ImplWriteActions( PDFWriter
& rWriter
, PDFExtOutDevData
* pPDFExtOutDevData
,
1056 const GDIMetaFile
& rInMtf
, VirtualDevice
& rDummyVDev
)
1058 bool bAssertionFired( false );
1061 bool bTransparenciesRemoved
= false;
1062 if( mbRemoveTransparencies
)
1064 bTransparenciesRemoved
= rWriter
.GetReferenceDevice()->
1065 RemoveTransparenciesFromMetaFile( rInMtf
, aMtf
, mnMaxImageResolution
, mnMaxImageResolution
,
1066 false, true, mbReduceImageResolution
);
1074 for( sal_uInt32 i
= 0, nCount
= aMtf
.GetActionCount(); i
< nCount
; )
1076 if ( !pPDFExtOutDevData
|| !pPDFExtOutDevData
->PlaySyncPageAct( rWriter
, i
) )
1078 const MetaAction
* pAction
= aMtf
.GetAction( i
);
1079 const USHORT nType
= pAction
->GetType();
1083 case( META_PIXEL_ACTION
):
1085 const MetaPixelAction
* pA
= (const MetaPixelAction
*) pAction
;
1086 rWriter
.DrawPixel( pA
->GetPoint(), pA
->GetColor() );
1090 case( META_POINT_ACTION
):
1092 const MetaPointAction
* pA
= (const MetaPointAction
*) pAction
;
1093 rWriter
.DrawPixel( pA
->GetPoint() );
1097 case( META_LINE_ACTION
):
1099 const MetaLineAction
* pA
= (const MetaLineAction
*) pAction
;
1100 if ( pA
->GetLineInfo().IsDefault() )
1101 rWriter
.DrawLine( pA
->GetStartPoint(), pA
->GetEndPoint() );
1103 rWriter
.DrawLine( pA
->GetStartPoint(), pA
->GetEndPoint(), pA
->GetLineInfo() );
1107 case( META_RECT_ACTION
):
1109 const MetaRectAction
* pA
= (const MetaRectAction
*) pAction
;
1110 rWriter
.DrawRect( pA
->GetRect() );
1114 case( META_ROUNDRECT_ACTION
):
1116 const MetaRoundRectAction
* pA
= (const MetaRoundRectAction
*) pAction
;
1117 rWriter
.DrawRect( pA
->GetRect(), pA
->GetHorzRound(), pA
->GetVertRound() );
1121 case( META_ELLIPSE_ACTION
):
1123 const MetaEllipseAction
* pA
= (const MetaEllipseAction
*) pAction
;
1124 rWriter
.DrawEllipse( pA
->GetRect() );
1128 case( META_ARC_ACTION
):
1130 const MetaArcAction
* pA
= (const MetaArcAction
*) pAction
;
1131 rWriter
.DrawArc( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint() );
1135 case( META_PIE_ACTION
):
1137 const MetaArcAction
* pA
= (const MetaArcAction
*) pAction
;
1138 rWriter
.DrawPie( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint() );
1142 case( META_CHORD_ACTION
):
1144 const MetaChordAction
* pA
= (const MetaChordAction
*) pAction
;
1145 rWriter
.DrawChord( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint() );
1149 case( META_POLYGON_ACTION
):
1151 const MetaPolygonAction
* pA
= (const MetaPolygonAction
*) pAction
;
1152 rWriter
.DrawPolygon( pA
->GetPolygon() );
1156 case( META_POLYLINE_ACTION
):
1158 const MetaPolyLineAction
* pA
= (const MetaPolyLineAction
*) pAction
;
1159 if ( pA
->GetLineInfo().IsDefault() )
1160 rWriter
.DrawPolyLine( pA
->GetPolygon() );
1162 rWriter
.DrawPolyLine( pA
->GetPolygon(), pA
->GetLineInfo() );
1166 case( META_POLYPOLYGON_ACTION
):
1168 const MetaPolyPolygonAction
* pA
= (const MetaPolyPolygonAction
*) pAction
;
1169 rWriter
.DrawPolyPolygon( pA
->GetPolyPolygon() );
1173 case( META_GRADIENT_ACTION
):
1175 const MetaGradientAction
* pA
= (const MetaGradientAction
*) pAction
;
1176 const PolyPolygon
aPolyPoly( pA
->GetRect() );
1178 ImplWriteGradient( rWriter
, aPolyPoly
, pA
->GetGradient(), rDummyVDev
);
1182 case( META_GRADIENTEX_ACTION
):
1184 const MetaGradientExAction
* pA
= (const MetaGradientExAction
*) pAction
;
1185 ImplWriteGradient( rWriter
, pA
->GetPolyPolygon(), pA
->GetGradient(), rDummyVDev
);
1189 case META_HATCH_ACTION
:
1191 const MetaHatchAction
* pA
= (const MetaHatchAction
*) pAction
;
1192 rWriter
.DrawHatch( pA
->GetPolyPolygon(), pA
->GetHatch() );
1196 case( META_TRANSPARENT_ACTION
):
1198 const MetaTransparentAction
* pA
= (const MetaTransparentAction
*) pAction
;
1199 rWriter
.DrawTransparent( pA
->GetPolyPolygon(), pA
->GetTransparence() );
1203 case( META_FLOATTRANSPARENT_ACTION
):
1205 const MetaFloatTransparentAction
* pA
= (const MetaFloatTransparentAction
*) pAction
;
1207 GDIMetaFile
aTmpMtf( pA
->GetGDIMetaFile() );
1208 const Point
& rPos
= pA
->GetPoint();
1209 const Size
& rSize
= pA
->GetSize();
1210 const Gradient
& rTransparenceGradient
= pA
->GetGradient();
1212 const Size
aDstSizeTwip( rDummyVDev
.PixelToLogic( rDummyVDev
.LogicToPixel( rSize
), MAP_TWIP
) );
1213 sal_Int32 nMaxBmpDPI
= mbUseLosslessCompression
? 300 : 72;
1214 if ( mbReduceImageResolution
)
1216 if ( nMaxBmpDPI
> mnMaxImageResolution
)
1217 nMaxBmpDPI
= mnMaxImageResolution
;
1219 const sal_Int32 nPixelX
= (sal_Int32
)((double)aDstSizeTwip
.Width() * (double)nMaxBmpDPI
/ 1440.0);
1220 const sal_Int32 nPixelY
= (sal_Int32
)((double)aDstSizeTwip
.Height() * (double)nMaxBmpDPI
/ 1440.0);
1221 if ( nPixelX
&& nPixelY
)
1223 Size
aDstSizePixel( nPixelX
, nPixelY
);
1224 VirtualDevice
* pVDev
= new VirtualDevice
;
1225 if( pVDev
->SetOutputSizePixel( aDstSizePixel
) )
1227 Bitmap aPaint
, aMask
;
1231 MapMode
aMapMode( rDummyVDev
.GetMapMode() );
1232 aMapMode
.SetOrigin( aPoint
);
1233 pVDev
->SetMapMode( aMapMode
);
1234 Size
aDstSize( pVDev
->PixelToLogic( aDstSizePixel
) );
1236 Point
aMtfOrigin( aTmpMtf
.GetPrefMapMode().GetOrigin() );
1237 if ( aMtfOrigin
.X() || aMtfOrigin
.Y() )
1238 aTmpMtf
.Move( -aMtfOrigin
.X(), -aMtfOrigin
.Y() );
1239 double fScaleX
= (double)aDstSize
.Width() / (double)aTmpMtf
.GetPrefSize().Width();
1240 double fScaleY
= (double)aDstSize
.Height() / (double)aTmpMtf
.GetPrefSize().Height();
1241 if( fScaleX
!= 1.0 || fScaleY
!= 1.0 )
1242 aTmpMtf
.Scale( fScaleX
, fScaleY
);
1243 aTmpMtf
.SetPrefMapMode( aMapMode
);
1245 // create paint bitmap
1246 aTmpMtf
.WindStart();
1247 aTmpMtf
.Play( pVDev
, aPoint
, aDstSize
);
1248 aTmpMtf
.WindStart();
1250 pVDev
->EnableMapMode( FALSE
);
1251 aPaint
= pVDev
->GetBitmap( aPoint
, aDstSizePixel
);
1252 pVDev
->EnableMapMode( TRUE
);
1254 // create mask bitmap
1255 pVDev
->SetLineColor( COL_BLACK
);
1256 pVDev
->SetFillColor( COL_BLACK
);
1257 pVDev
->DrawRect( Rectangle( aPoint
, aDstSize
) );
1258 pVDev
->SetDrawMode( DRAWMODE_WHITELINE
| DRAWMODE_WHITEFILL
| DRAWMODE_WHITETEXT
|
1259 DRAWMODE_WHITEBITMAP
| DRAWMODE_WHITEGRADIENT
);
1260 aTmpMtf
.WindStart();
1261 aTmpMtf
.Play( pVDev
, aPoint
, aDstSize
);
1262 aTmpMtf
.WindStart();
1263 pVDev
->EnableMapMode( FALSE
);
1264 aMask
= pVDev
->GetBitmap( aPoint
, aDstSizePixel
);
1265 pVDev
->EnableMapMode( TRUE
);
1267 // create alpha mask from gradient
1268 pVDev
->SetDrawMode( DRAWMODE_GRAYGRADIENT
);
1269 pVDev
->DrawGradient( Rectangle( aPoint
, aDstSize
), rTransparenceGradient
);
1270 pVDev
->SetDrawMode( DRAWMODE_DEFAULT
);
1271 pVDev
->EnableMapMode( FALSE
);
1272 pVDev
->DrawMask( aPoint
, aDstSizePixel
, aMask
, Color( COL_WHITE
) );
1273 aAlpha
= pVDev
->GetBitmap( aPoint
, aDstSizePixel
);
1274 ImplWriteBitmapEx( rWriter
, rDummyVDev
, rPos
, rSize
, BitmapEx( aPaint
, aAlpha
) );
1281 case( META_EPS_ACTION
):
1283 const MetaEPSAction
* pA
= (const MetaEPSAction
*) pAction
;
1284 const GDIMetaFile
aSubstitute( pA
->GetSubstitute() );
1289 MapMode
aMapMode( aSubstitute
.GetPrefMapMode() );
1290 Size
aOutSize( rDummyVDev
.LogicToLogic( pA
->GetSize(), rDummyVDev
.GetMapMode(), aMapMode
) );
1291 aMapMode
.SetScaleX( Fraction( aOutSize
.Width(), aSubstitute
.GetPrefSize().Width() ) );
1292 aMapMode
.SetScaleY( Fraction( aOutSize
.Height(), aSubstitute
.GetPrefSize().Height() ) );
1293 aMapMode
.SetOrigin( rDummyVDev
.LogicToLogic( pA
->GetPoint(), rDummyVDev
.GetMapMode(), aMapMode
) );
1295 rWriter
.SetMapMode( aMapMode
);
1296 rDummyVDev
.SetMapMode( aMapMode
);
1297 ImplWriteActions( rWriter
, NULL
, aSubstitute
, rDummyVDev
);
1303 case( META_COMMENT_ACTION
):
1304 if( ! bTransparenciesRemoved
)
1306 const MetaCommentAction
* pA
= (const MetaCommentAction
*) pAction
;
1307 String aSkipComment
;
1309 if( pA
->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL
)
1311 const MetaGradientExAction
* pGradAction
= NULL
;
1312 sal_Bool bDone
= sal_False
;
1314 while( !bDone
&& ( ++i
< nCount
) )
1316 pAction
= aMtf
.GetAction( i
);
1318 if( pAction
->GetType() == META_GRADIENTEX_ACTION
)
1319 pGradAction
= (const MetaGradientExAction
*) pAction
;
1320 else if( ( pAction
->GetType() == META_COMMENT_ACTION
) &&
1321 ( ( (const MetaCommentAction
*) pAction
)->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_END" ) == COMPARE_EQUAL
) )
1328 ImplWriteGradient( rWriter
, pGradAction
->GetPolyPolygon(), pGradAction
->GetGradient(), rDummyVDev
);
1332 const BYTE
* pData
= pA
->GetData();
1335 SvMemoryStream
aMemStm( (void*)pData
, pA
->GetDataSize(), STREAM_READ
);
1336 sal_Bool bSkipSequence
= sal_False
;
1339 if( pA
->GetComment().Equals( "XPATHSTROKE_SEQ_BEGIN" ) )
1341 sSeqEnd
= ByteString( "XPATHSTROKE_SEQ_END" );
1342 SvtGraphicStroke aStroke
;
1346 aStroke
.getPath( aPath
);
1348 PolyPolygon aStartArrow
;
1349 PolyPolygon aEndArrow
;
1350 double fTransparency( aStroke
.getTransparency() );
1351 double fStrokeWidth( aStroke
.getStrokeWidth() );
1352 SvtGraphicStroke::JoinType
eJT( aStroke
.getJoinType() );
1353 SvtGraphicStroke::DashArray aDashArray
;
1355 aStroke
.getStartArrow( aStartArrow
);
1356 aStroke
.getEndArrow( aEndArrow
);
1357 aStroke
.getDashArray( aDashArray
);
1359 bSkipSequence
= sal_True
;
1360 if ( aStartArrow
.Count() || aEndArrow
.Count() )
1361 bSkipSequence
= sal_False
;
1362 if ( (sal_uInt32
)eJT
> 2 )
1363 bSkipSequence
= sal_False
;
1364 if ( aDashArray
.size() && ( fStrokeWidth
!= 0.0 ) && ( fTransparency
== 0.0 ) )
1365 bSkipSequence
= sal_False
;
1366 if ( bSkipSequence
)
1368 PDFWriter::ExtLineInfo aInfo
;
1369 aInfo
.m_fLineWidth
= fStrokeWidth
;
1370 aInfo
.m_fTransparency
= fTransparency
;
1371 aInfo
.m_fMiterLimit
= aStroke
.getMiterLimit();
1372 switch( aStroke
.getCapType() )
1375 case SvtGraphicStroke::capButt
: aInfo
.m_eCap
= PDFWriter::capButt
;break;
1376 case SvtGraphicStroke::capRound
: aInfo
.m_eCap
= PDFWriter::capRound
;break;
1377 case SvtGraphicStroke::capSquare
: aInfo
.m_eCap
= PDFWriter::capSquare
;break;
1379 switch( aStroke
.getJoinType() )
1382 case SvtGraphicStroke::joinMiter
: aInfo
.m_eJoin
= PDFWriter::joinMiter
;break;
1383 case SvtGraphicStroke::joinRound
: aInfo
.m_eJoin
= PDFWriter::joinRound
;break;
1384 case SvtGraphicStroke::joinBevel
: aInfo
.m_eJoin
= PDFWriter::joinBevel
;break;
1385 case SvtGraphicStroke::joinNone
:
1386 aInfo
.m_eJoin
= PDFWriter::joinMiter
;
1387 aInfo
.m_fMiterLimit
= 0.0;
1390 aInfo
.m_aDashArray
= aDashArray
;
1391 rWriter
.DrawPolyLine( aPath
, aInfo
);
1394 else if ( pA
->GetComment().Equals( "XPATHFILL_SEQ_BEGIN" ) )
1396 sSeqEnd
= ByteString( "XPATHFILL_SEQ_END" );
1397 SvtGraphicFill aFill
;
1400 if ( ( aFill
.getFillType() == SvtGraphicFill::fillSolid
) && ( aFill
.getFillRule() == SvtGraphicFill::fillEvenOdd
) )
1402 double fTransparency
= aFill
.getTransparency();
1403 if ( fTransparency
== 0.0 )
1406 aFill
.getPath( aPath
);
1408 bSkipSequence
= sal_True
;
1409 rWriter
.DrawPolyPolygon( aPath
);
1411 else if ( fTransparency
== 1.0 )
1412 bSkipSequence
= sal_True
;
1414 /* #i81548# removing optimization for fill textures, because most of the texture settings are not
1415 exported properly. In OpenOffice 3.1 the drawing layer will support graphic primitives, then it
1416 will not be a problem to optimize the filltexture export. But for wysiwyg is more important than
1418 else if( aFill.getFillType() == SvtGraphicFill::fillTexture && aFill.isTiling() )
1420 sal_Int32 nPattern = mnCachePatternId;
1421 Graphic aPatternGraphic;
1422 aFill.getGraphic( aPatternGraphic );
1423 bool bUseCache = false;
1424 SvtGraphicFill::Transform aPatTransform;
1425 aFill.getTransform( aPatTransform );
1427 if( mnCachePatternId >= 0 )
1429 SvtGraphicFill::Transform aCacheTransform;
1430 maCacheFill.getTransform( aCacheTransform );
1431 if( aCacheTransform.matrix[0] == aPatTransform.matrix[0] &&
1432 aCacheTransform.matrix[1] == aPatTransform.matrix[1] &&
1433 aCacheTransform.matrix[2] == aPatTransform.matrix[2] &&
1434 aCacheTransform.matrix[3] == aPatTransform.matrix[3] &&
1435 aCacheTransform.matrix[4] == aPatTransform.matrix[4] &&
1436 aCacheTransform.matrix[5] == aPatTransform.matrix[5]
1439 Graphic aCacheGraphic;
1440 maCacheFill.getGraphic( aCacheGraphic );
1441 if( aCacheGraphic == aPatternGraphic )
1449 // paint graphic to metafile
1450 GDIMetaFile aPattern;
1451 rDummyVDev.SetConnectMetaFile( &aPattern );
1453 rDummyVDev.SetMapMode( aPatternGraphic.GetPrefMapMode() );
1455 aPatternGraphic.Draw( &rDummyVDev, Point( 0, 0 ) );
1457 rDummyVDev.SetConnectMetaFile( NULL );
1458 aPattern.WindStart();
1460 MapMode aPatternMapMode( aPatternGraphic.GetPrefMapMode() );
1461 // prepare pattern from metafile
1462 Size aPrefSize( aPatternGraphic.GetPrefSize() );
1463 // FIXME: this magic -1 shouldn't be necessary
1464 aPrefSize.Width() -= 1;
1465 aPrefSize.Height() -= 1;
1466 aPrefSize = rWriter.GetReferenceDevice()->
1467 LogicToLogic( aPrefSize,
1469 &rWriter.GetReferenceDevice()->GetMapMode() );
1470 // build bounding rectangle of pattern
1471 Rectangle aBound( Point( 0, 0 ), aPrefSize );
1472 rWriter.BeginPattern( aBound );
1475 rWriter.SetMapMode( aPatternMapMode );
1476 rDummyVDev.SetMapMode( aPatternMapMode );
1477 ImplWriteActions( rWriter, NULL, aPattern, rDummyVDev );
1481 nPattern = rWriter.EndPattern( aPatTransform );
1483 // try some caching and reuse pattern
1484 mnCachePatternId = nPattern;
1485 maCacheFill = aFill;
1488 // draw polypolygon with pattern fill
1490 aFill.getPath( aPath );
1491 rWriter.DrawPolyPolygon( aPath, nPattern, aFill.getFillRule() == SvtGraphicFill::fillEvenOdd );
1493 bSkipSequence = sal_True;
1497 if ( bSkipSequence
)
1499 while( ++i
< nCount
)
1501 pAction
= aMtf
.GetAction( i
);
1502 if ( pAction
->GetType() == META_COMMENT_ACTION
)
1504 ByteString
sComment( ((MetaCommentAction
*)pAction
)->GetComment() );
1505 if ( sComment
.Equals( sSeqEnd
) )
1509 // the replacement action for stroke is a filled rectangle
1510 // the set fillcolor of the replacement is part of the graphics
1511 // state and must not be skipped
1512 else if( pAction
->GetType() == META_FILLCOLOR_ACTION
)
1514 const MetaFillColorAction
* pMA
= (const MetaFillColorAction
*) pAction
;
1515 if( pMA
->IsSetting() )
1516 rWriter
.SetFillColor( pMA
->GetColor() );
1518 rWriter
.SetFillColor();
1527 case( META_BMP_ACTION
):
1529 const MetaBmpAction
* pA
= (const MetaBmpAction
*) pAction
;
1530 BitmapEx
aBitmapEx( pA
->GetBitmap() );
1531 Size
aSize( OutputDevice::LogicToLogic( aBitmapEx
.GetPrefSize(),
1532 aBitmapEx
.GetPrefMapMode(), rDummyVDev
.GetMapMode() ) );
1533 if( ! ( aSize
.Width() && aSize
.Height() ) )
1534 aSize
= rDummyVDev
.PixelToLogic( aBitmapEx
.GetSizePixel() );
1535 ImplWriteBitmapEx( rWriter
, rDummyVDev
, pA
->GetPoint(), aSize
, aBitmapEx
);
1539 case( META_BMPSCALE_ACTION
):
1541 const MetaBmpScaleAction
* pA
= (const MetaBmpScaleAction
*) pAction
;
1542 ImplWriteBitmapEx( rWriter
, rDummyVDev
, pA
->GetPoint(), pA
->GetSize(), BitmapEx( pA
->GetBitmap() ) );
1546 case( META_BMPSCALEPART_ACTION
):
1548 const MetaBmpScalePartAction
* pA
= (const MetaBmpScalePartAction
*) pAction
;
1549 BitmapEx
aBitmapEx( pA
->GetBitmap() );
1550 aBitmapEx
.Crop( Rectangle( pA
->GetSrcPoint(), pA
->GetSrcSize() ) );
1551 ImplWriteBitmapEx( rWriter
, rDummyVDev
, pA
->GetDestPoint(), pA
->GetDestSize(), aBitmapEx
);
1555 case( META_BMPEX_ACTION
):
1557 const MetaBmpExAction
* pA
= (const MetaBmpExAction
*) pAction
;
1558 BitmapEx
aBitmapEx( pA
->GetBitmapEx() );
1559 Size
aSize( OutputDevice::LogicToLogic( aBitmapEx
.GetPrefSize(),
1560 aBitmapEx
.GetPrefMapMode(), rDummyVDev
.GetMapMode() ) );
1561 ImplWriteBitmapEx( rWriter
, rDummyVDev
, pA
->GetPoint(), aSize
, aBitmapEx
);
1565 case( META_BMPEXSCALE_ACTION
):
1567 const MetaBmpExScaleAction
* pA
= (const MetaBmpExScaleAction
*) pAction
;
1568 ImplWriteBitmapEx( rWriter
, rDummyVDev
, pA
->GetPoint(), pA
->GetSize(), pA
->GetBitmapEx() );
1572 case( META_BMPEXSCALEPART_ACTION
):
1574 const MetaBmpExScalePartAction
* pA
= (const MetaBmpExScalePartAction
*) pAction
;
1575 BitmapEx
aBitmapEx( pA
->GetBitmapEx() );
1576 aBitmapEx
.Crop( Rectangle( pA
->GetSrcPoint(), pA
->GetSrcSize() ) );
1577 ImplWriteBitmapEx( rWriter
, rDummyVDev
, pA
->GetDestPoint(), pA
->GetDestSize(), aBitmapEx
);
1581 case( META_MASK_ACTION
):
1582 case( META_MASKSCALE_ACTION
):
1583 case( META_MASKSCALEPART_ACTION
):
1585 DBG_ERROR( "MetaMask...Action not supported yet" );
1589 case( META_TEXT_ACTION
):
1591 const MetaTextAction
* pA
= (const MetaTextAction
*) pAction
;
1592 rWriter
.DrawText( pA
->GetPoint(), String( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() ) );
1596 case( META_TEXTRECT_ACTION
):
1598 const MetaTextRectAction
* pA
= (const MetaTextRectAction
*) pAction
;
1599 rWriter
.DrawText( pA
->GetRect(), String( pA
->GetText() ), pA
->GetStyle() );
1603 case( META_TEXTARRAY_ACTION
):
1605 const MetaTextArrayAction
* pA
= (const MetaTextArrayAction
*) pAction
;
1606 rWriter
.DrawTextArray( pA
->GetPoint(), pA
->GetText(), pA
->GetDXArray(), pA
->GetIndex(), pA
->GetLen() );
1610 case( META_STRETCHTEXT_ACTION
):
1612 const MetaStretchTextAction
* pA
= (const MetaStretchTextAction
*) pAction
;
1613 rWriter
.DrawStretchText( pA
->GetPoint(), pA
->GetWidth(), pA
->GetText(), pA
->GetIndex(), pA
->GetLen() );
1618 case( META_TEXTLINE_ACTION
):
1620 const MetaTextLineAction
* pA
= (const MetaTextLineAction
*) pAction
;
1621 rWriter
.DrawTextLine( pA
->GetStartPoint(), pA
->GetWidth(), pA
->GetStrikeout(), pA
->GetUnderline(), pA
->GetOverline() );
1626 case( META_CLIPREGION_ACTION
):
1628 const MetaClipRegionAction
* pA
= (const MetaClipRegionAction
*) pAction
;
1630 if( pA
->IsClipping() )
1631 rWriter
.SetClipRegion( pA
->GetRegion() );
1633 rWriter
.SetClipRegion();
1637 case( META_ISECTRECTCLIPREGION_ACTION
):
1639 const MetaISectRectClipRegionAction
* pA
= (const MetaISectRectClipRegionAction
*) pAction
;
1640 rWriter
.IntersectClipRegion( pA
->GetRect() );
1644 case( META_ISECTREGIONCLIPREGION_ACTION
):
1646 const MetaISectRegionClipRegionAction
* pA
= (const MetaISectRegionClipRegionAction
*) pAction
;
1647 rWriter
.IntersectClipRegion( pA
->GetRegion() );
1651 case( META_MOVECLIPREGION_ACTION
):
1653 const MetaMoveClipRegionAction
* pA
= (const MetaMoveClipRegionAction
*) pAction
;
1654 rWriter
.MoveClipRegion( pA
->GetHorzMove(), pA
->GetVertMove() );
1658 case( META_MAPMODE_ACTION
):
1660 const_cast< MetaAction
* >( pAction
)->Execute( &rDummyVDev
);
1661 rWriter
.SetMapMode( rDummyVDev
.GetMapMode() );
1665 case( META_LINECOLOR_ACTION
):
1667 const MetaLineColorAction
* pA
= (const MetaLineColorAction
*) pAction
;
1669 if( pA
->IsSetting() )
1670 rWriter
.SetLineColor( pA
->GetColor() );
1672 rWriter
.SetLineColor();
1676 case( META_FILLCOLOR_ACTION
):
1678 const MetaFillColorAction
* pA
= (const MetaFillColorAction
*) pAction
;
1680 if( pA
->IsSetting() )
1681 rWriter
.SetFillColor( pA
->GetColor() );
1683 rWriter
.SetFillColor();
1687 case( META_TEXTLINECOLOR_ACTION
):
1689 const MetaTextLineColorAction
* pA
= (const MetaTextLineColorAction
*) pAction
;
1691 if( pA
->IsSetting() )
1692 rWriter
.SetTextLineColor( pA
->GetColor() );
1694 rWriter
.SetTextLineColor();
1698 case( META_OVERLINECOLOR_ACTION
):
1700 const MetaOverlineColorAction
* pA
= (const MetaOverlineColorAction
*) pAction
;
1702 if( pA
->IsSetting() )
1703 rWriter
.SetOverlineColor( pA
->GetColor() );
1705 rWriter
.SetOverlineColor();
1709 case( META_TEXTFILLCOLOR_ACTION
):
1711 const MetaTextFillColorAction
* pA
= (const MetaTextFillColorAction
*) pAction
;
1713 if( pA
->IsSetting() )
1714 rWriter
.SetTextFillColor( pA
->GetColor() );
1716 rWriter
.SetTextFillColor();
1720 case( META_TEXTCOLOR_ACTION
):
1722 const MetaTextColorAction
* pA
= (const MetaTextColorAction
*) pAction
;
1723 rWriter
.SetTextColor( pA
->GetColor() );
1727 case( META_TEXTALIGN_ACTION
):
1729 const MetaTextAlignAction
* pA
= (const MetaTextAlignAction
*) pAction
;
1730 rWriter
.SetTextAlign( pA
->GetTextAlign() );
1734 case( META_FONT_ACTION
):
1736 const MetaFontAction
* pA
= (const MetaFontAction
*) pAction
;
1737 rWriter
.SetFont( pA
->GetFont() );
1741 case( META_PUSH_ACTION
):
1743 const MetaPushAction
* pA
= (const MetaPushAction
*) pAction
;
1745 rDummyVDev
.Push( pA
->GetFlags() );
1746 rWriter
.Push( pA
->GetFlags() );
1750 case( META_POP_ACTION
):
1757 case( META_LAYOUTMODE_ACTION
):
1759 const MetaLayoutModeAction
* pA
= (const MetaLayoutModeAction
*) pAction
;
1760 rWriter
.SetLayoutMode( pA
->GetLayoutMode() );
1764 case META_TEXTLANGUAGE_ACTION
:
1766 const MetaTextLanguageAction
* pA
= (const MetaTextLanguageAction
*) pAction
;
1767 rWriter
.SetDigitLanguage( pA
->GetTextLanguage() );
1771 case( META_WALLPAPER_ACTION
):
1773 const MetaWallpaperAction
* pA
= (const MetaWallpaperAction
*) pAction
;
1774 rWriter
.DrawWallpaper( pA
->GetRect(), pA
->GetWallpaper() );
1778 case( META_RASTEROP_ACTION
):
1780 // !!! >>> we don't want to support this actions
1784 case( META_REFPOINT_ACTION
):
1786 // !!! >>> we don't want to support this actions
1791 // #i24604# Made assertion fire only once per
1792 // metafile. The asserted actions here are all
1794 if( !bAssertionFired
)
1796 bAssertionFired
= true;
1797 DBG_ERROR( "PDFExport::ImplWriteActions: deprecated and unsupported MetaAction encountered" );
1808 // -----------------------------------------------------------------------------
1810 void PDFExport::ImplWriteGradient( PDFWriter
& rWriter
, const PolyPolygon
& rPolyPoly
, const Gradient
& rGradient
, VirtualDevice
& rDummyVDev
)
1812 GDIMetaFile aTmpMtf
;
1814 rDummyVDev
.AddGradientActions( rPolyPoly
.GetBoundRect(), rGradient
, aTmpMtf
);
1817 rWriter
.IntersectClipRegion( rPolyPoly
);
1818 ImplWriteActions( rWriter
, NULL
, aTmpMtf
, rDummyVDev
);
1822 // -----------------------------------------------------------------------------
1824 void PDFExport::ImplWriteBitmapEx( PDFWriter
& rWriter
, VirtualDevice
& rDummyVDev
,
1825 const Point
& rPoint
, const Size
& rSize
, const BitmapEx
& rBitmapEx
)
1827 if ( !rBitmapEx
.IsEmpty() && rSize
.Width() && rSize
.Height() )
1829 BitmapEx
aBitmapEx( rBitmapEx
);
1830 Point
aPoint( rPoint
);
1831 Size
aSize( rSize
);
1833 // #i19065# Negative sizes have mirror semantics on
1834 // OutputDevice. BitmapEx and co. have no idea about that, so
1835 // perform that _before_ doing anything with aBitmapEx.
1836 ULONG
nMirrorFlags(BMP_MIRROR_NONE
);
1837 if( aSize
.Width() < 0 )
1839 aSize
.Width() *= -1;
1840 aPoint
.X() -= aSize
.Width();
1841 nMirrorFlags
|= BMP_MIRROR_HORZ
;
1843 if( aSize
.Height() < 0 )
1845 aSize
.Height() *= -1;
1846 aPoint
.Y() -= aSize
.Height();
1847 nMirrorFlags
|= BMP_MIRROR_VERT
;
1850 if( nMirrorFlags
!= BMP_MIRROR_NONE
)
1852 aBitmapEx
.Mirror( nMirrorFlags
);
1854 if ( mbReduceImageResolution
)
1856 // do downsampling if neccessary
1857 const Size
aDstSizeTwip( rDummyVDev
.PixelToLogic( rDummyVDev
.LogicToPixel( aSize
), MAP_TWIP
) );
1858 const Size
aBmpSize( aBitmapEx
.GetSizePixel() );
1859 const double fBmpPixelX
= aBmpSize
.Width();
1860 const double fBmpPixelY
= aBmpSize
.Height();
1861 const double fMaxPixelX
= aDstSizeTwip
.Width() * mnMaxImageResolution
/ 1440.0;
1862 const double fMaxPixelY
= aDstSizeTwip
.Height() * mnMaxImageResolution
/ 1440.0;
1864 // check, if the bitmap DPI exceeds the maximum DPI (allow 4 pixel rounding tolerance)
1865 if( ( ( fBmpPixelX
> ( fMaxPixelX
+ 4 ) ) ||
1866 ( fBmpPixelY
> ( fMaxPixelY
+ 4 ) ) ) &&
1867 ( fBmpPixelY
> 0.0 ) && ( fMaxPixelY
> 0.0 ) )
1871 const double fBmpWH
= fBmpPixelX
/ fBmpPixelY
;
1872 const double fMaxWH
= fMaxPixelX
/ fMaxPixelY
;
1874 if( fBmpWH
< fMaxWH
)
1876 aNewBmpSize
.Width() = FRound( fMaxPixelY
* fBmpWH
);
1877 aNewBmpSize
.Height() = FRound( fMaxPixelY
);
1879 else if( fBmpWH
> 0.0 )
1881 aNewBmpSize
.Width() = FRound( fMaxPixelX
);
1882 aNewBmpSize
.Height() = FRound( fMaxPixelX
/ fBmpWH
);
1884 if( aNewBmpSize
.Width() && aNewBmpSize
.Height() )
1885 aBitmapEx
.Scale( aNewBmpSize
);
1887 aBitmapEx
.SetEmpty();
1891 const Size
aSizePixel( aBitmapEx
.GetSizePixel() );
1892 if ( aSizePixel
.Width() && aSizePixel
.Height() )
1894 sal_Bool bUseJPGCompression
= !mbUseLosslessCompression
;
1895 if ( ( aSizePixel
.Width() < 32 ) || ( aSizePixel
.Height() < 32 ) )
1896 bUseJPGCompression
= sal_False
;
1898 SvMemoryStream aStrm
;
1901 if ( bUseJPGCompression
)
1903 sal_uInt32 nZippedFileSize
; // sj: we will calculate the filesize of a zipped bitmap
1904 { // to determine if jpeg compression is usefull
1905 SvMemoryStream aTemp
;
1906 aTemp
.SetCompressMode( aTemp
.GetCompressMode() | COMPRESSMODE_ZBITMAP
);
1907 aTemp
.SetVersion( SOFFICE_FILEFORMAT_40
); // sj: up from version 40 our bitmap stream operator
1908 aTemp
<< aBitmapEx
; // is capable of zlib stream compression
1909 aTemp
.Seek( STREAM_SEEK_TO_END
);
1910 nZippedFileSize
= aTemp
.Tell();
1912 if ( aBitmapEx
.IsTransparent() )
1914 if ( aBitmapEx
.IsAlpha() )
1915 aMask
= aBitmapEx
.GetAlpha().GetBitmap();
1917 aMask
= aBitmapEx
.GetMask();
1919 GraphicFilter aGraphicFilter
;
1920 Graphic
aGraphic( aBitmapEx
.GetBitmap() );
1921 sal_uInt16 nFormatName
= aGraphicFilter
.GetExportFormatNumberForShortName( OUString( RTL_CONSTASCII_USTRINGPARAM( "JPG" ) ) );
1922 sal_Int32 nColorMode
= 0;
1924 Sequence
< PropertyValue
> aFilterData( 2 );
1925 aFilterData
[ 0 ].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "Quality" ) );
1926 aFilterData
[ 0 ].Value
<<= mnQuality
;
1927 aFilterData
[ 1 ].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "ColorMode" ) );
1928 aFilterData
[ 1 ].Value
<<= nColorMode
;
1930 /*sal_uInt16 nError =*/ aGraphicFilter
.ExportGraphic( aGraphic
, String(), aStrm
, nFormatName
, &aFilterData
);
1931 aStrm
.Seek( STREAM_SEEK_TO_END
);
1932 if ( aStrm
.Tell() > nZippedFileSize
)
1933 bUseJPGCompression
= sal_False
;
1935 if ( bUseJPGCompression
)
1936 rWriter
.DrawJPGBitmap( aStrm
, true, aSizePixel
, Rectangle( aPoint
, aSize
), aMask
);
1937 else if ( aBitmapEx
.IsTransparent() )
1938 rWriter
.DrawBitmapEx( aPoint
, aSize
, aBitmapEx
);
1940 rWriter
.DrawBitmap( aPoint
, aSize
, aBitmapEx
.GetBitmap() );