diff options
Diffstat (limited to 'filter/source/pdf/pdfexport.cxx')
-rw-r--r-- | filter/source/pdf/pdfexport.cxx | 1184 |
1 files changed, 207 insertions, 977 deletions
diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx index f8c0dbc20739..3f3177f64082 100644 --- a/filter/source/pdf/pdfexport.cxx +++ b/filter/source/pdf/pdfexport.cxx @@ -33,46 +33,58 @@ #include "impdialog.hxx" #include "pdf.hrc" -#include <tools/urlobj.hxx> -#include <tools/fract.hxx> -#include <tools/poly.hxx> -#include <vcl/mapmod.hxx> -#include <vcl/virdev.hxx> -#include <vcl/metaact.hxx> -#include <vcl/gdimtf.hxx> -#include <vcl/jobset.hxx> -#include <vcl/salbtype.hxx> -#include <vcl/bmpacc.hxx> +#include "tools/urlobj.hxx" +#include "tools/fract.hxx" +#include "tools/poly.hxx" +#include "vcl/mapmod.hxx" +#include "vcl/virdev.hxx" +#include "vcl/metaact.hxx" +#include "vcl/gdimtf.hxx" +#include "vcl/jobset.hxx" +#include "vcl/salbtype.hxx" +#include "vcl/bmpacc.hxx" #include "vcl/svapp.hxx" -#include <toolkit/awt/vclxdevice.hxx> -#include <unotools/localfilehelper.hxx> -#include <unotools/processfactory.hxx> -#include <svtools/FilterConfigItem.hxx> -#include <svtools/filter.hxx> -#include <svl/solar.hrc> -#include <comphelper/string.hxx> +#include "toolkit/awt/vclxdevice.hxx" +#include "unotools/localfilehelper.hxx" +#include "unotools/processfactory.hxx" +#include "svtools/FilterConfigItem.hxx" +#include "svtools/filter.hxx" +#include "svl/solar.hrc" +#include "comphelper/string.hxx" +#include "comphelper/storagehelper.hxx" +#include "unotools/streamwrap.hxx" +#include "com/sun/star/io/XSeekable.hpp" + #include "basegfx/polygon/b2dpolygon.hxx" #include "basegfx/polygon/b2dpolypolygon.hxx" #include "basegfx/polygon/b2dpolygontools.hxx" -#include <unotools/saveopt.hxx> // only for testing of relative saving options in PDF - -#include <vcl/graphictools.hxx> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/awt/Rectangle.hpp> -#include <com/sun/star/awt/XDevice.hpp> -#include <com/sun/star/util/MeasureUnit.hpp> -#include <com/sun/star/frame/XModel.hpp> -#include <com/sun/star/frame/XModuleManager.hpp> -#include <com/sun/star/frame/XStorable.hpp> -#include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/document/XDocumentProperties.hpp> -#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> -#include <com/sun/star/container/XNameAccess.hpp> -#include <com/sun/star/view/XViewSettingsSupplier.hpp> -#include <unotools/configmgr.hxx> -#include <com/sun/star/lang/XServiceInfo.hpp> -#include <com/sun/star/drawing/XShapes.hpp> +#include "unotools/saveopt.hxx" // only for testing of relative saving options in PDF + +#include "vcl/graphictools.hxx" +#include "com/sun/star/beans/XPropertySet.hpp" +#include "com/sun/star/awt/Rectangle.hpp" +#include "com/sun/star/awt/XDevice.hpp" +#include "com/sun/star/util/MeasureUnit.hpp" +#include "com/sun/star/frame/XModel.hpp" +#include "com/sun/star/frame/XModuleManager.hpp" +#include "com/sun/star/frame/XStorable.hpp" +#include "com/sun/star/frame/XController.hpp" +#include "com/sun/star/document/XDocumentProperties.hpp" +#include "com/sun/star/document/XDocumentPropertiesSupplier.hpp" +#include "com/sun/star/container/XNameAccess.hpp" +#include "com/sun/star/view/XViewSettingsSupplier.hpp" +#include "com/sun/star/task/XInteractionRequest.hpp" +#include "com/sun/star/task/PDFExportException.hpp" + +#include "unotools/configmgr.hxx" +#include "cppuhelper/exc_hlp.hxx" +#include "cppuhelper/compbase1.hxx" +#include "cppuhelper/basemutex.hxx" + +#include "com/sun/star/lang/XServiceInfo.hpp" +#include "com/sun/star/drawing/XShapes.hpp" +#include "com/sun/star/graphic/XGraphicProvider.hpp" using namespace ::rtl; using namespace ::vcl; @@ -81,15 +93,20 @@ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::view; +using namespace ::com::sun::star::graphic; // ------------- // - PDFExport - // ------------- -PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc, Reference< task::XStatusIndicator >& rxStatusIndicator, const Reference< lang::XMultiServiceFactory >& xFactory ) : +PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc, + const Reference< task::XStatusIndicator >& rxStatusIndicator, + const Reference< task::XInteractionHandler >& rxIH, + const Reference< lang::XMultiServiceFactory >& xFactory ) : mxSrcDoc ( rxSrcDoc ), mxMSF ( xFactory ), mxStatusIndicator ( rxStatusIndicator ), + mxIH ( rxIH ), mbUseTaggedPDF ( sal_False ), mnPDFTypeSelection ( 0 ), mbExportNotes ( sal_True ), @@ -127,9 +144,7 @@ PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc, Reference< task:: mbFirstPageLeft ( sal_False ), mbEncrypt ( sal_False ), - msOpenPassword (), mbRestrictPermissions ( sal_False ), - msPermissionPassword (), mnPrintAllowed ( 2 ), mnChangesAllowed ( 4 ), mbCanCopyOrExtract ( sal_True ), @@ -197,7 +212,7 @@ sal_Bool PDFExport::ExportSelection( vcl::PDFWriter& rPDFWriter, Reference< com: const Size aMtfSize( aPageSize.Width, aPageSize.Height ); pOut->Push(); - pOut->EnableOutput( FALSE ); + pOut->EnableOutput( sal_False ); pOut->SetMapMode( aMapMode ); aMtf.SetPrefSize( aMtfSize ); @@ -246,12 +261,12 @@ sal_Bool PDFExport::ExportSelection( vcl::PDFWriter& rPDFWriter, Reference< com: class PDFExportStreamDoc : public vcl::PDFOutputStream { - Reference< XComponent > m_xSrcDoc; - rtl::OUString m_aPassWd; + Reference< XComponent > m_xSrcDoc; + Sequence< beans::NamedValue > m_aPreparedPassword; public: - PDFExportStreamDoc( const Reference< XComponent >& xDoc, const rtl::OUString& rPwd ) + PDFExportStreamDoc( const Reference< XComponent >& xDoc, const Sequence<beans::NamedValue>& rPwd ) : m_xSrcDoc( xDoc ), - m_aPassWd( rPwd ) + m_aPreparedPassword( rPwd ) {} virtual ~PDFExportStreamDoc(); @@ -267,15 +282,16 @@ void PDFExportStreamDoc::write( const Reference< XOutputStream >& xStream ) Reference< com::sun::star::frame::XStorable > xStore( m_xSrcDoc, UNO_QUERY ); if( xStore.is() ) { - Sequence< beans::PropertyValue > aArgs( m_aPassWd.getLength() ? 3 : 2 ); + Sequence< beans::PropertyValue > aArgs( 2 + ((m_aPreparedPassword.getLength() > 0) ? 1 : 0) ); aArgs.getArray()[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) ); aArgs.getArray()[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) ); aArgs.getArray()[1].Value <<= xStream; - if( m_aPassWd.getLength() ) + if( m_aPreparedPassword.getLength() ) { - aArgs.getArray()[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ); - aArgs.getArray()[2].Value <<= m_aPassWd; + aArgs.getArray()[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionData" ) ); + aArgs.getArray()[2].Value <<= m_aPreparedPassword; } + try { xStore->storeToURL( OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ), @@ -386,6 +402,11 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue VCLXDevice* pXDevice = new VCLXDevice; OUString aPageRange; Any aSelection; + PDFWriter::PDFWriterContext aContext; + rtl::OUString aOpenPassword, aPermissionPassword; + Reference< beans::XMaterialHolder > xEnc; + Sequence< beans::NamedValue > aPreparedPermissionPassword; + // getting the string for the creator String aCreator; @@ -404,7 +425,34 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue aCreator.AppendAscii( "Math" ); } - PDFWriter::PDFWriterContext aContext; + Reference< document::XDocumentPropertiesSupplier > xDocumentPropsSupplier( mxSrcDoc, UNO_QUERY ); + if ( xDocumentPropsSupplier.is() ) + { + Reference< document::XDocumentProperties > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties() ); + if ( xDocumentProps.is() ) + { + aContext.DocumentInfo.Title = xDocumentProps->getTitle(); + aContext.DocumentInfo.Author = xDocumentProps->getAuthor(); + aContext.DocumentInfo.Subject = xDocumentProps->getSubject(); + aContext.DocumentInfo.Keywords = ::comphelper::string::convertCommaSeparated(xDocumentProps->getKeywords()); + } + } + // getting the string for the producer + String aProducer; + ::utl::ConfigManager* pMgr = ::utl::ConfigManager::GetConfigManager(); + if ( pMgr ) + { + Any aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME ); + ::rtl::OUString sProductName; + aProductName >>= sProductName; + aProducer = sProductName; + aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION ); + aProductName >>= sProductName; + aProducer.AppendAscii(" "); + aProducer += String( sProductName ); + } + aContext.DocumentInfo.Producer = aProducer; + aContext.DocumentInfo.Creator = aCreator; for( sal_Int32 nData = 0, nDataCount = rFilterData.getLength(); nData < nDataCount; ++nData ) { @@ -478,11 +526,15 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptFile" ) ) ) rFilterData[ nData ].Value >>= mbEncrypt; else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentOpenPassword" ) ) ) - rFilterData[ nData ].Value >>= msOpenPassword; + rFilterData[ nData ].Value >>= aOpenPassword; else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "RestrictPermissions" ) ) ) rFilterData[ nData ].Value >>= mbRestrictPermissions; else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PermissionPassword" ) ) ) - rFilterData[ nData ].Value >>= msPermissionPassword; + rFilterData[ nData ].Value >>= aPermissionPassword; + else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPasswords" ) ) ) + rFilterData[ nData ].Value >>= xEnc; + else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPermissionPassword" ) ) ) + rFilterData[ nData ].Value >>= aPreparedPermissionPassword; else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Printing" ) ) ) rFilterData[ nData ].Value >>= mnPrintAllowed; else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Changes" ) ) ) @@ -517,14 +569,17 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue break; case 1: aContext.Version = PDFWriter::PDF_A_1; -//force the tagged PDF as well + //force the tagged PDF as well mbUseTaggedPDF = sal_True; -//force embedding of standard fonts + //force embedding of standard fonts mbEmbedStandardFonts = sal_True; -//force disabling of form conversion + //force disabling of form conversion mbExportFormFields = sal_False; -// PDF/A does not allow transparencies + // PDF/A does not allow transparencies mbRemoveTransparencies = sal_True; + // no encryption + mbEncrypt = sal_False; + xEnc.clear(); break; } @@ -600,23 +655,17 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue if( aContext.Version != PDFWriter::PDF_A_1 ) { //set values needed in encryption - aContext.Encrypt = mbEncrypt; //set encryption level, fixed, but here it can set by the UI if needed. // true is 128 bit, false 40 //note that in 40 bit mode the UI needs reworking, since the current UI is meaningfull only for //128bit security mode - aContext.Security128bit = sal_True; - -//set the open password - if( aContext.Encrypt && msOpenPassword.getLength() > 0 ) - aContext.UserPassword = msOpenPassword; + aContext.Encryption.Security128bit = sal_True; //set check for permission change password // if not enabled and no permission password, force permissions to default as if PDF where without encryption - if( mbRestrictPermissions && msPermissionPassword.getLength() > 0 ) + if( mbRestrictPermissions && (xEnc.is() || aPermissionPassword.getLength() > 0) ) { - aContext.OwnerPassword = msPermissionPassword; - aContext.Encrypt = sal_True; + mbEncrypt = sal_True; //permission set as desired, done after } else @@ -634,9 +683,9 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue break; default: case 2: - aContext.AccessPermissions.CanPrintFull = sal_True; + aContext.Encryption.CanPrintFull = sal_True; case 1: - aContext.AccessPermissions.CanPrintTheDocument = sal_True; + aContext.Encryption.CanPrintTheDocument = sal_True; break; } @@ -645,26 +694,36 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue case 0: //already in struct PDFSecPermissions CTOR break; case 1: - aContext.AccessPermissions.CanAssemble = sal_True; + aContext.Encryption.CanAssemble = sal_True; break; case 2: - aContext.AccessPermissions.CanFillInteractive = sal_True; + aContext.Encryption.CanFillInteractive = sal_True; break; case 3: - aContext.AccessPermissions.CanAddOrModify = sal_True; + aContext.Encryption.CanAddOrModify = sal_True; break; default: case 4: - aContext.AccessPermissions.CanModifyTheContent = - aContext.AccessPermissions.CanCopyOrExtract = - aContext.AccessPermissions.CanAddOrModify = - aContext.AccessPermissions.CanFillInteractive = sal_True; + aContext.Encryption.CanModifyTheContent = + aContext.Encryption.CanCopyOrExtract = + aContext.Encryption.CanAddOrModify = + aContext.Encryption.CanFillInteractive = sal_True; break; } - aContext.AccessPermissions.CanCopyOrExtract = mbCanCopyOrExtract; - aContext.AccessPermissions.CanExtractForAccessibility = mbCanExtractForAccessibility; + aContext.Encryption.CanCopyOrExtract = mbCanCopyOrExtract; + aContext.Encryption.CanExtractForAccessibility = mbCanExtractForAccessibility; + if( mbEncrypt && ! xEnc.is() ) + xEnc = PDFWriter::InitEncryption( aPermissionPassword, aOpenPassword, aContext.Encryption.Security128bit ); + if( mbEncrypt && aPermissionPassword.getLength() && ! aPreparedPermissionPassword.getLength() ) + aPreparedPermissionPassword = comphelper::OStorageHelper::CreatePackageEncryptionData( aPermissionPassword ); } + // after this point we don't need the legacy clear passwords anymore + // however they are still inside the passed filter data sequence + // which is sadly out out our control + aPermissionPassword = rtl::OUString(); + aOpenPassword = rtl::OUString(); + /* * FIXME: the entries are only implicitly defined by the resource file. Should there * ever be an additional form submit format this could get invalid. @@ -727,7 +786,7 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue //<--- } // all context data set, time to create the printing device - PDFWriter* pPDFWriter = new PDFWriter( aContext ); + PDFWriter* pPDFWriter = new PDFWriter( aContext, xEnc ); OutputDevice* pOut = pPDFWriter->GetReferenceDevice(); vcl::PDFExtOutDevData* pPDFExtOutDevData = NULL; @@ -740,38 +799,10 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue // get mimetype OUString aSrcMimetype = getMimetypeForDocument( mxMSF, mxSrcDoc ); pPDFWriter->AddStream( aSrcMimetype, - new PDFExportStreamDoc( mxSrcDoc, msPermissionPassword ), + new PDFExportStreamDoc( mxSrcDoc, aPreparedPermissionPassword ), false ); } - PDFDocInfo aDocInfo; - Reference< document::XDocumentPropertiesSupplier > xDocumentPropsSupplier( mxSrcDoc, UNO_QUERY ); - if ( xDocumentPropsSupplier.is() ) - { - Reference< document::XDocumentProperties > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties() ); - if ( xDocumentProps.is() ) - { - aDocInfo.Title = xDocumentProps->getTitle(); - aDocInfo.Author = xDocumentProps->getAuthor(); - aDocInfo.Subject = xDocumentProps->getSubject(); - aDocInfo.Keywords = ::comphelper::string::convertCommaSeparated(xDocumentProps->getKeywords()); - } - } - // getting the string for the producer - String aProducer; - ::utl::ConfigManager& rMgr = ::utl::ConfigManager::GetConfigManager(); - Any aProductName = rMgr.GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME ); - ::rtl::OUString sProductName; - aProductName >>= sProductName; - aProducer = sProductName; - aProductName = rMgr.GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION ); - aProductName >>= sProductName; - aProducer.AppendAscii(" "); - aProducer += String( sProductName ); - aDocInfo.Producer = aProducer; - aDocInfo.Creator = aCreator; - - pPDFWriter->SetDocInfo( aDocInfo ); if ( pOut ) { @@ -870,7 +901,7 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue if( nPageCount > 0 ) bRet = ExportSelection( *pPDFWriter, xRenderable, aSelection, aMultiSelection, aRenderOptions, nPageCount ); else - bRet = FALSE; + bRet = sal_False; if ( bRet && bSecondPassForImpressNotes ) { @@ -915,12 +946,59 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue return bRet; } +namespace +{ + +typedef cppu::WeakComponentImplHelper1< task::XInteractionRequest > PDFErrorRequestBase; + +class PDFErrorRequest : private cppu::BaseMutex, + public PDFErrorRequestBase +{ + task::PDFExportException maExc; +public: + PDFErrorRequest( const task::PDFExportException& i_rExc ); + + // XInteractionRequest + virtual uno::Any SAL_CALL getRequest() throw (uno::RuntimeException); + virtual uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL getContinuations() throw (uno::RuntimeException); +}; + +PDFErrorRequest::PDFErrorRequest( const task::PDFExportException& i_rExc ) : + PDFErrorRequestBase( m_aMutex ), + maExc( i_rExc ) +{ +} + +uno::Any SAL_CALL PDFErrorRequest::getRequest() throw (uno::RuntimeException) +{ + osl::MutexGuard const guard( m_aMutex ); + + uno::Any aRet; + aRet <<= maExc; + return aRet; +} + +uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL PDFErrorRequest::getContinuations() throw (uno::RuntimeException) +{ + return uno::Sequence< uno::Reference< task::XInteractionContinuation > >(); +} + +} // namespace + void PDFExport::showErrors( const std::set< PDFWriter::ErrorCode >& rErrors ) { - if( ! rErrors.empty() ) + if( ! rErrors.empty() && mxIH.is() ) { - ImplErrorDialog aDlg( rErrors ); - aDlg.Execute(); + task::PDFExportException aExc; + aExc.ErrorCodes.realloc( sal_Int32(rErrors.size()) ); + sal_Int32 i = 0; + for( std::set< PDFWriter::ErrorCode >::const_iterator it = rErrors.begin(); + it != rErrors.end(); ++it, i++ ) + { + aExc.ErrorCodes.getArray()[i] = (sal_Int32)*it; + } + Reference< task::XInteractionRequest > xReq( new PDFErrorRequest( aExc ) ); + mxIH->handle( xReq ); } } @@ -928,21 +1006,36 @@ void PDFExport::showErrors( const std::set< PDFWriter::ErrorCode >& rErrors ) sal_Bool PDFExport::ImplExportPage( PDFWriter& rWriter, PDFExtOutDevData& rPDFExtOutDevData, const GDIMetaFile& rMtf ) { - VirtualDevice aDummyVDev; const Size aSizePDF( OutputDevice::LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_POINT ) ); Point aOrigin; Rectangle aPageRect( aOrigin, rMtf.GetPrefSize() ); - sal_Bool bRet = sal_False; - - aDummyVDev.EnableOutput( sal_False ); - aDummyVDev.SetMapMode( rMtf.GetPrefMapMode() ); + sal_Bool bRet = sal_True; rWriter.NewPage( aSizePDF.Width(), aSizePDF.Height() ); rWriter.SetMapMode( rMtf.GetPrefMapMode() ); + vcl::PDFWriter::PlayMetafileContext aCtx; + GDIMetaFile aMtf; + if( mbRemoveTransparencies ) + { + aCtx.m_bTransparenciesWereRemoved = rWriter.GetReferenceDevice()-> + RemoveTransparenciesFromMetaFile( rMtf, aMtf, mnMaxImageResolution, mnMaxImageResolution, + false, true, mbReduceImageResolution ); + } + else + { + aMtf = rMtf; + } + aCtx.m_nMaxImageResolution = mbReduceImageResolution ? mnMaxImageResolution : 0; + aCtx.m_bOnlyLosslessCompression = mbUseLosslessCompression; + aCtx.m_nJPEGQuality = mnQuality; + + basegfx::B2DRectangle aB2DRect( aPageRect.Left(), aPageRect.Top(), aPageRect.Right(), aPageRect.Bottom() ); rWriter.SetClipRegion( basegfx::B2DPolyPolygon( basegfx::tools::createPolygonFromRect( aB2DRect ) ) ); - bRet = ImplWriteActions( rWriter, &rPDFExtOutDevData, rMtf, aDummyVDev ); + + rWriter.PlayMetafile( aMtf, aCtx, &rPDFExtOutDevData ); + rPDFExtOutDevData.ResetSyncData(); if( mbWatermark ) @@ -1024,868 +1117,5 @@ void PDFExport::ImplWriteWatermark( PDFWriter& rWriter, const Size& rPageSize ) rWriter.Pop(); } -// ----------------------------------------------------------------------------- - -sal_Bool PDFExport::ImplWriteActions( PDFWriter& rWriter, PDFExtOutDevData* pPDFExtOutDevData, - const GDIMetaFile& rInMtf, VirtualDevice& rDummyVDev ) -{ - bool bAssertionFired( false ); - - GDIMetaFile aMtf; - bool bTransparenciesRemoved = false; - if( mbRemoveTransparencies ) - { - bTransparenciesRemoved = rWriter.GetReferenceDevice()-> - RemoveTransparenciesFromMetaFile( rInMtf, aMtf, mnMaxImageResolution, mnMaxImageResolution, - false, true, mbReduceImageResolution ); - } - else - { - aMtf = rInMtf; - } - - - for( sal_uInt32 i = 0, nCount = aMtf.GetActionCount(); i < nCount; ) - { - if ( !pPDFExtOutDevData || !pPDFExtOutDevData->PlaySyncPageAct( rWriter, i ) ) - { - const MetaAction* pAction = aMtf.GetAction( i ); - const USHORT nType = pAction->GetType(); - - switch( nType ) - { - case( META_PIXEL_ACTION ): - { - const MetaPixelAction* pA = (const MetaPixelAction*) pAction; - rWriter.DrawPixel( pA->GetPoint(), pA->GetColor() ); - } - break; - - case( META_POINT_ACTION ): - { - const MetaPointAction* pA = (const MetaPointAction*) pAction; - rWriter.DrawPixel( pA->GetPoint() ); - } - break; - - case( META_LINE_ACTION ): - { - const MetaLineAction* pA = (const MetaLineAction*) pAction; - if ( pA->GetLineInfo().IsDefault() ) - rWriter.DrawLine( pA->GetStartPoint(), pA->GetEndPoint() ); - else - rWriter.DrawLine( pA->GetStartPoint(), pA->GetEndPoint(), pA->GetLineInfo() ); - } - break; - - case( META_RECT_ACTION ): - { - const MetaRectAction* pA = (const MetaRectAction*) pAction; - rWriter.DrawRect( pA->GetRect() ); - } - break; - - case( META_ROUNDRECT_ACTION ): - { - const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pAction; - rWriter.DrawRect( pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() ); - } - break; - - case( META_ELLIPSE_ACTION ): - { - const MetaEllipseAction* pA = (const MetaEllipseAction*) pAction; - rWriter.DrawEllipse( pA->GetRect() ); - } - break; - - case( META_ARC_ACTION ): - { - const MetaArcAction* pA = (const MetaArcAction*) pAction; - rWriter.DrawArc( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() ); - } - break; - - case( META_PIE_ACTION ): - { - const MetaArcAction* pA = (const MetaArcAction*) pAction; - rWriter.DrawPie( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() ); - } - break; - - case( META_CHORD_ACTION ): - { - const MetaChordAction* pA = (const MetaChordAction*) pAction; - rWriter.DrawChord( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() ); - } - break; - - case( META_POLYGON_ACTION ): - { - const MetaPolygonAction* pA = (const MetaPolygonAction*) pAction; - rWriter.DrawPolygon( pA->GetPolygon() ); - } - break; - - case( META_POLYLINE_ACTION ): - { - const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pAction; - if ( pA->GetLineInfo().IsDefault() ) - rWriter.DrawPolyLine( pA->GetPolygon() ); - else - rWriter.DrawPolyLine( pA->GetPolygon(), pA->GetLineInfo() ); - } - break; - - case( META_POLYPOLYGON_ACTION ): - { - const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pAction; - rWriter.DrawPolyPolygon( pA->GetPolyPolygon() ); - } - break; - - case( META_GRADIENT_ACTION ): - { - const MetaGradientAction* pA = (const MetaGradientAction*) pAction; - const PolyPolygon aPolyPoly( pA->GetRect() ); - - ImplWriteGradient( rWriter, aPolyPoly, pA->GetGradient(), rDummyVDev ); - } - break; - - case( META_GRADIENTEX_ACTION ): - { - const MetaGradientExAction* pA = (const MetaGradientExAction*) pAction; - ImplWriteGradient( rWriter, pA->GetPolyPolygon(), pA->GetGradient(), rDummyVDev ); - } - break; - - case META_HATCH_ACTION: - { - const MetaHatchAction* pA = (const MetaHatchAction*) pAction; - rWriter.DrawHatch( pA->GetPolyPolygon(), pA->GetHatch() ); - } - break; - - case( META_TRANSPARENT_ACTION ): - { - const MetaTransparentAction* pA = (const MetaTransparentAction*) pAction; - rWriter.DrawTransparent( pA->GetPolyPolygon(), pA->GetTransparence() ); - } - break; - - case( META_FLOATTRANSPARENT_ACTION ): - { - const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pAction; - - GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() ); - const Point& rPos = pA->GetPoint(); - const Size& rSize= pA->GetSize(); - const Gradient& rTransparenceGradient = pA->GetGradient(); - - // special case constant alpha value - if( rTransparenceGradient.GetStartColor() == rTransparenceGradient.GetEndColor() ) - { - const Color aTransCol( rTransparenceGradient.GetStartColor() ); - const USHORT nTransPercent = aTransCol.GetLuminance() * 100 / 255; - rWriter.BeginTransparencyGroup(); - ImplWriteActions( rWriter, NULL, aTmpMtf, rDummyVDev ); - rWriter.EndTransparencyGroup( Rectangle( rPos, rSize ), nTransPercent ); - } - else - { - const Size aDstSizeTwip( rDummyVDev.PixelToLogic( rDummyVDev.LogicToPixel( rSize ), MAP_TWIP ) ); - sal_Int32 nMaxBmpDPI = mbUseLosslessCompression ? 300 : 72; - if ( mbReduceImageResolution ) - { - if ( nMaxBmpDPI > mnMaxImageResolution ) - nMaxBmpDPI = mnMaxImageResolution; - } - const sal_Int32 nPixelX = (sal_Int32)((double)aDstSizeTwip.Width() * (double)nMaxBmpDPI / 1440.0); - const sal_Int32 nPixelY = (sal_Int32)((double)aDstSizeTwip.Height() * (double)nMaxBmpDPI / 1440.0); - if ( nPixelX && nPixelY ) - { - Size aDstSizePixel( nPixelX, nPixelY ); - VirtualDevice* pVDev = new VirtualDevice; - if( pVDev->SetOutputSizePixel( aDstSizePixel ) ) - { - Bitmap aPaint, aMask; - AlphaMask aAlpha; - Point aPoint; - - MapMode aMapMode( rDummyVDev.GetMapMode() ); - aMapMode.SetOrigin( aPoint ); - pVDev->SetMapMode( aMapMode ); - Size aDstSize( pVDev->PixelToLogic( aDstSizePixel ) ); - - Point aMtfOrigin( aTmpMtf.GetPrefMapMode().GetOrigin() ); - if ( aMtfOrigin.X() || aMtfOrigin.Y() ) - aTmpMtf.Move( -aMtfOrigin.X(), -aMtfOrigin.Y() ); - double fScaleX = (double)aDstSize.Width() / (double)aTmpMtf.GetPrefSize().Width(); - double fScaleY = (double)aDstSize.Height() / (double)aTmpMtf.GetPrefSize().Height(); - if( fScaleX != 1.0 || fScaleY != 1.0 ) - aTmpMtf.Scale( fScaleX, fScaleY ); - aTmpMtf.SetPrefMapMode( aMapMode ); - - // create paint bitmap - aTmpMtf.WindStart(); - aTmpMtf.Play( pVDev, aPoint, aDstSize ); - aTmpMtf.WindStart(); - - pVDev->EnableMapMode( FALSE ); - aPaint = pVDev->GetBitmap( aPoint, aDstSizePixel ); - pVDev->EnableMapMode( TRUE ); - - // create mask bitmap - pVDev->SetLineColor( COL_BLACK ); - pVDev->SetFillColor( COL_BLACK ); - pVDev->DrawRect( Rectangle( aPoint, aDstSize ) ); - pVDev->SetDrawMode( DRAWMODE_WHITELINE | DRAWMODE_WHITEFILL | DRAWMODE_WHITETEXT | - DRAWMODE_WHITEBITMAP | DRAWMODE_WHITEGRADIENT ); - aTmpMtf.WindStart(); - aTmpMtf.Play( pVDev, aPoint, aDstSize ); - aTmpMtf.WindStart(); - pVDev->EnableMapMode( FALSE ); - aMask = pVDev->GetBitmap( aPoint, aDstSizePixel ); - pVDev->EnableMapMode( TRUE ); - - // create alpha mask from gradient - pVDev->SetDrawMode( DRAWMODE_GRAYGRADIENT ); - pVDev->DrawGradient( Rectangle( aPoint, aDstSize ), rTransparenceGradient ); - pVDev->SetDrawMode( DRAWMODE_DEFAULT ); - pVDev->EnableMapMode( FALSE ); - pVDev->DrawMask( aPoint, aDstSizePixel, aMask, Color( COL_WHITE ) ); - aAlpha = pVDev->GetBitmap( aPoint, aDstSizePixel ); - ImplWriteBitmapEx( rWriter, rDummyVDev, rPos, rSize, BitmapEx( aPaint, aAlpha ) ); - } - delete pVDev; - } - } - } - break; - - case( META_EPS_ACTION ): - { - const MetaEPSAction* pA = (const MetaEPSAction*) pAction; - const GDIMetaFile aSubstitute( pA->GetSubstitute() ); - - rWriter.Push(); - rDummyVDev.Push(); - - MapMode aMapMode( aSubstitute.GetPrefMapMode() ); - Size aOutSize( rDummyVDev.LogicToLogic( pA->GetSize(), rDummyVDev.GetMapMode(), aMapMode ) ); - aMapMode.SetScaleX( Fraction( aOutSize.Width(), aSubstitute.GetPrefSize().Width() ) ); - aMapMode.SetScaleY( Fraction( aOutSize.Height(), aSubstitute.GetPrefSize().Height() ) ); - aMapMode.SetOrigin( rDummyVDev.LogicToLogic( pA->GetPoint(), rDummyVDev.GetMapMode(), aMapMode ) ); - - rWriter.SetMapMode( aMapMode ); - rDummyVDev.SetMapMode( aMapMode ); - ImplWriteActions( rWriter, NULL, aSubstitute, rDummyVDev ); - rDummyVDev.Pop(); - rWriter.Pop(); - } - break; - - case( META_COMMENT_ACTION ): - if( ! bTransparenciesRemoved ) - { - const MetaCommentAction* pA = (const MetaCommentAction*) pAction; - String aSkipComment; - - if( pA->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL ) - { - const MetaGradientExAction* pGradAction = NULL; - sal_Bool bDone = sal_False; - - while( !bDone && ( ++i < nCount ) ) - { - pAction = aMtf.GetAction( i ); - - if( pAction->GetType() == META_GRADIENTEX_ACTION ) - pGradAction = (const MetaGradientExAction*) pAction; - else if( ( pAction->GetType() == META_COMMENT_ACTION ) && - ( ( (const MetaCommentAction*) pAction )->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_END" ) == COMPARE_EQUAL ) ) - { - bDone = sal_True; - } - } - - if( pGradAction ) - ImplWriteGradient( rWriter, pGradAction->GetPolyPolygon(), pGradAction->GetGradient(), rDummyVDev ); - } - else - { - const BYTE* pData = pA->GetData(); - if ( pData ) - { - SvMemoryStream aMemStm( (void*)pData, pA->GetDataSize(), STREAM_READ ); - sal_Bool bSkipSequence = sal_False; - ByteString sSeqEnd; - - if( pA->GetComment().Equals( "XPATHSTROKE_SEQ_BEGIN" ) ) - { - sSeqEnd = ByteString( "XPATHSTROKE_SEQ_END" ); - SvtGraphicStroke aStroke; - aMemStm >> aStroke; - - Polygon aPath; - aStroke.getPath( aPath ); - - PolyPolygon aStartArrow; - PolyPolygon aEndArrow; - double fTransparency( aStroke.getTransparency() ); - double fStrokeWidth( aStroke.getStrokeWidth() ); - SvtGraphicStroke::DashArray aDashArray; - - aStroke.getStartArrow( aStartArrow ); - aStroke.getEndArrow( aEndArrow ); - aStroke.getDashArray( aDashArray ); - - bSkipSequence = sal_True; - if ( aStartArrow.Count() || aEndArrow.Count() ) - bSkipSequence = sal_False; - if ( aDashArray.size() && ( fStrokeWidth != 0.0 ) && ( fTransparency == 0.0 ) ) - bSkipSequence = sal_False; - if ( bSkipSequence ) - { - PDFWriter::ExtLineInfo aInfo; - aInfo.m_fLineWidth = fStrokeWidth; - aInfo.m_fTransparency = fTransparency; - aInfo.m_fMiterLimit = aStroke.getMiterLimit(); - switch( aStroke.getCapType() ) - { - default: - case SvtGraphicStroke::capButt: aInfo.m_eCap = PDFWriter::capButt;break; - case SvtGraphicStroke::capRound: aInfo.m_eCap = PDFWriter::capRound;break; - case SvtGraphicStroke::capSquare: aInfo.m_eCap = PDFWriter::capSquare;break; - } - switch( aStroke.getJoinType() ) - { - default: - case SvtGraphicStroke::joinMiter: aInfo.m_eJoin = PDFWriter::joinMiter;break; - case SvtGraphicStroke::joinRound: aInfo.m_eJoin = PDFWriter::joinRound;break; - case SvtGraphicStroke::joinBevel: aInfo.m_eJoin = PDFWriter::joinBevel;break; - case SvtGraphicStroke::joinNone: - aInfo.m_eJoin = PDFWriter::joinMiter; - aInfo.m_fMiterLimit = 0.0; - break; - } - aInfo.m_aDashArray = aDashArray; - - if(SvtGraphicStroke::joinNone == aStroke.getJoinType() - && fStrokeWidth > 0.0) - { - // emulate no edge rounding by handling single edges - const sal_uInt16 nPoints(aPath.GetSize()); - const bool bCurve(aPath.HasFlags()); - - for(sal_uInt16 a(0); a + 1 < nPoints; a++) - { - if(bCurve - && POLY_NORMAL != aPath.GetFlags(a + 1) - && a + 2 < nPoints - && POLY_NORMAL != aPath.GetFlags(a + 2) - && a + 3 < nPoints) - { - const Polygon aSnippet(4, - aPath.GetConstPointAry() + a, - aPath.GetConstFlagAry() + a); - rWriter.DrawPolyLine( aSnippet, aInfo ); - a += 2; - } - else - { - const Polygon aSnippet(2, - aPath.GetConstPointAry() + a); - rWriter.DrawPolyLine( aSnippet, aInfo ); - } - } - } - else - { - rWriter.DrawPolyLine( aPath, aInfo ); - } - } - } - else if ( pA->GetComment().Equals( "XPATHFILL_SEQ_BEGIN" ) ) - { - sSeqEnd = ByteString( "XPATHFILL_SEQ_END" ); - SvtGraphicFill aFill; - aMemStm >> aFill; - - if ( ( aFill.getFillType() == SvtGraphicFill::fillSolid ) && ( aFill.getFillRule() == SvtGraphicFill::fillEvenOdd ) ) - { - double fTransparency = aFill.getTransparency(); - if ( fTransparency == 0.0 ) - { - PolyPolygon aPath; - aFill.getPath( aPath ); - - bSkipSequence = sal_True; - rWriter.DrawPolyPolygon( aPath ); - } - else if ( fTransparency == 1.0 ) - bSkipSequence = sal_True; - } - } - if ( bSkipSequence ) - { - while( ++i < nCount ) - { - pAction = aMtf.GetAction( i ); - if ( pAction->GetType() == META_COMMENT_ACTION ) - { - ByteString sComment( ((MetaCommentAction*)pAction)->GetComment() ); - if ( sComment.Equals( sSeqEnd ) ) - break; - } - // #i44496# - // the replacement action for stroke is a filled rectangle - // the set fillcolor of the replacement is part of the graphics - // state and must not be skipped - else if( pAction->GetType() == META_FILLCOLOR_ACTION ) - { - const MetaFillColorAction* pMA = (const MetaFillColorAction*) pAction; - if( pMA->IsSetting() ) - rWriter.SetFillColor( pMA->GetColor() ); - else - rWriter.SetFillColor(); - } - } - } - } - } - } - break; - - case( META_BMP_ACTION ): - { - const MetaBmpAction* pA = (const MetaBmpAction*) pAction; - BitmapEx aBitmapEx( pA->GetBitmap() ); - Size aSize( OutputDevice::LogicToLogic( aBitmapEx.GetPrefSize(), - aBitmapEx.GetPrefMapMode(), rDummyVDev.GetMapMode() ) ); - if( ! ( aSize.Width() && aSize.Height() ) ) - aSize = rDummyVDev.PixelToLogic( aBitmapEx.GetSizePixel() ); - ImplWriteBitmapEx( rWriter, rDummyVDev, pA->GetPoint(), aSize, aBitmapEx ); - } - break; - - case( META_BMPSCALE_ACTION ): - { - const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pAction; - ImplWriteBitmapEx( rWriter, rDummyVDev, pA->GetPoint(), pA->GetSize(), BitmapEx( pA->GetBitmap() ) ); - } - break; - - case( META_BMPSCALEPART_ACTION ): - { - const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pAction; - BitmapEx aBitmapEx( pA->GetBitmap() ); - aBitmapEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ); - ImplWriteBitmapEx( rWriter, rDummyVDev, pA->GetDestPoint(), pA->GetDestSize(), aBitmapEx ); - } - break; - - case( META_BMPEX_ACTION ): - { - const MetaBmpExAction* pA = (const MetaBmpExAction*) pAction; - BitmapEx aBitmapEx( pA->GetBitmapEx() ); - Size aSize( OutputDevice::LogicToLogic( aBitmapEx.GetPrefSize(), - aBitmapEx.GetPrefMapMode(), rDummyVDev.GetMapMode() ) ); - ImplWriteBitmapEx( rWriter, rDummyVDev, pA->GetPoint(), aSize, aBitmapEx ); - } - break; - - case( META_BMPEXSCALE_ACTION ): - { - const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction; - ImplWriteBitmapEx( rWriter, rDummyVDev, pA->GetPoint(), pA->GetSize(), pA->GetBitmapEx() ); - } - break; - - case( META_BMPEXSCALEPART_ACTION ): - { - const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pAction; - BitmapEx aBitmapEx( pA->GetBitmapEx() ); - aBitmapEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ); - ImplWriteBitmapEx( rWriter, rDummyVDev, pA->GetDestPoint(), pA->GetDestSize(), aBitmapEx ); - } - break; - - case( META_MASK_ACTION ): - case( META_MASKSCALE_ACTION ): - case( META_MASKSCALEPART_ACTION ): - { - OSL_FAIL( "MetaMask...Action not supported yet" ); - } - break; - - case( META_TEXT_ACTION ): - { - const MetaTextAction* pA = (const MetaTextAction*) pAction; - rWriter.DrawText( pA->GetPoint(), String( pA->GetText(), pA->GetIndex(), pA->GetLen() ) ); - } - break; - - case( META_TEXTRECT_ACTION ): - { - const MetaTextRectAction* pA = (const MetaTextRectAction*) pAction; - rWriter.DrawText( pA->GetRect(), String( pA->GetText() ), pA->GetStyle() ); - } - break; - - case( META_TEXTARRAY_ACTION ): - { - const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pAction; - rWriter.DrawTextArray( pA->GetPoint(), pA->GetText(), pA->GetDXArray(), pA->GetIndex(), pA->GetLen() ); - } - break; - - case( META_STRETCHTEXT_ACTION ): - { - const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pAction; - rWriter.DrawStretchText( pA->GetPoint(), pA->GetWidth(), pA->GetText(), pA->GetIndex(), pA->GetLen() ); - } - break; - - - case( META_TEXTLINE_ACTION ): - { - const MetaTextLineAction* pA = (const MetaTextLineAction*) pAction; - rWriter.DrawTextLine( pA->GetStartPoint(), pA->GetWidth(), pA->GetStrikeout(), pA->GetUnderline(), pA->GetOverline() ); - - } - break; - - case( META_CLIPREGION_ACTION ): - { - const MetaClipRegionAction* pA = (const MetaClipRegionAction*) pAction; - - if( pA->IsClipping() ) - { - if( pA->GetRegion().IsEmpty() ) - rWriter.SetClipRegion( basegfx::B2DPolyPolygon() ); - else - { - Region aReg( pA->GetRegion() ); - rWriter.SetClipRegion( aReg.ConvertToB2DPolyPolygon() ); - } - } - else - rWriter.SetClipRegion(); - } - break; - - case( META_ISECTRECTCLIPREGION_ACTION ): - { - const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pAction; - rWriter.IntersectClipRegion( pA->GetRect() ); - } - break; - - case( META_ISECTREGIONCLIPREGION_ACTION ): - { - const MetaISectRegionClipRegionAction* pA = (const MetaISectRegionClipRegionAction*) pAction; - Region aReg( pA->GetRegion() ); - rWriter.IntersectClipRegion( aReg.ConvertToB2DPolyPolygon() ); - } - break; - - case( META_MOVECLIPREGION_ACTION ): - { - const MetaMoveClipRegionAction* pA = (const MetaMoveClipRegionAction*) pAction; - rWriter.MoveClipRegion( pA->GetHorzMove(), pA->GetVertMove() ); - } - break; - - case( META_MAPMODE_ACTION ): - { - const_cast< MetaAction* >( pAction )->Execute( &rDummyVDev ); - rWriter.SetMapMode( rDummyVDev.GetMapMode() ); - } - break; - - case( META_LINECOLOR_ACTION ): - { - const MetaLineColorAction* pA = (const MetaLineColorAction*) pAction; - - if( pA->IsSetting() ) - rWriter.SetLineColor( pA->GetColor() ); - else - rWriter.SetLineColor(); - } - break; - - case( META_FILLCOLOR_ACTION ): - { - const MetaFillColorAction* pA = (const MetaFillColorAction*) pAction; - - if( pA->IsSetting() ) - rWriter.SetFillColor( pA->GetColor() ); - else - rWriter.SetFillColor(); - } - break; - - case( META_TEXTLINECOLOR_ACTION ): - { - const MetaTextLineColorAction* pA = (const MetaTextLineColorAction*) pAction; - - if( pA->IsSetting() ) - rWriter.SetTextLineColor( pA->GetColor() ); - else - rWriter.SetTextLineColor(); - } - break; - - case( META_OVERLINECOLOR_ACTION ): - { - const MetaOverlineColorAction* pA = (const MetaOverlineColorAction*) pAction; - - if( pA->IsSetting() ) - rWriter.SetOverlineColor( pA->GetColor() ); - else - rWriter.SetOverlineColor(); - } - break; - - case( META_TEXTFILLCOLOR_ACTION ): - { - const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*) pAction; - - if( pA->IsSetting() ) - rWriter.SetTextFillColor( pA->GetColor() ); - else - rWriter.SetTextFillColor(); - } - break; - - case( META_TEXTCOLOR_ACTION ): - { - const MetaTextColorAction* pA = (const MetaTextColorAction*) pAction; - rWriter.SetTextColor( pA->GetColor() ); - } - break; - - case( META_TEXTALIGN_ACTION ): - { - const MetaTextAlignAction* pA = (const MetaTextAlignAction*) pAction; - rWriter.SetTextAlign( pA->GetTextAlign() ); - } - break; - - case( META_FONT_ACTION ): - { - const MetaFontAction* pA = (const MetaFontAction*) pAction; - rWriter.SetFont( pA->GetFont() ); - } - break; - - case( META_PUSH_ACTION ): - { - const MetaPushAction* pA = (const MetaPushAction*) pAction; - - rDummyVDev.Push( pA->GetFlags() ); - rWriter.Push( pA->GetFlags() ); - } - break; - - case( META_POP_ACTION ): - { - rDummyVDev.Pop(); - rWriter.Pop(); - } - break; - - case( META_LAYOUTMODE_ACTION ): - { - const MetaLayoutModeAction* pA = (const MetaLayoutModeAction*) pAction; - rWriter.SetLayoutMode( pA->GetLayoutMode() ); - } - break; - - case META_TEXTLANGUAGE_ACTION: - { - const MetaTextLanguageAction* pA = (const MetaTextLanguageAction*) pAction; - rWriter.SetDigitLanguage( pA->GetTextLanguage() ); - } - break; - - case( META_WALLPAPER_ACTION ): - { - const MetaWallpaperAction* pA = (const MetaWallpaperAction*) pAction; - rWriter.DrawWallpaper( pA->GetRect(), pA->GetWallpaper() ); - } - break; - - case( META_RASTEROP_ACTION ): - { - // !!! >>> we don't want to support this actions - } - break; - - case( META_REFPOINT_ACTION ): - { - // !!! >>> we don't want to support this actions - } - break; - - default: - // #i24604# Made assertion fire only once per - // metafile. The asserted actions here are all - // deprecated - if( !bAssertionFired ) - { - bAssertionFired = true; - OSL_FAIL( "PDFExport::ImplWriteActions: deprecated and unsupported MetaAction encountered" ); - } - break; - } - i++; - } - } - - return sal_True; -} - -// ----------------------------------------------------------------------------- - -void PDFExport::ImplWriteGradient( PDFWriter& rWriter, const PolyPolygon& rPolyPoly, const Gradient& rGradient, VirtualDevice& rDummyVDev ) -{ - GDIMetaFile aTmpMtf; - - rDummyVDev.AddGradientActions( rPolyPoly.GetBoundRect(), rGradient, aTmpMtf ); - - rWriter.Push(); - rWriter.IntersectClipRegion( rPolyPoly.getB2DPolyPolygon() ); - ImplWriteActions( rWriter, NULL, aTmpMtf, rDummyVDev ); - rWriter.Pop(); -} - -// ----------------------------------------------------------------------------- - -void PDFExport::ImplWriteBitmapEx( PDFWriter& rWriter, VirtualDevice& rDummyVDev, - const Point& rPoint, const Size& rSize, const BitmapEx& rBitmapEx ) -{ - if ( !rBitmapEx.IsEmpty() && rSize.Width() && rSize.Height() ) - { - BitmapEx aBitmapEx( rBitmapEx ); - Point aPoint( rPoint ); - Size aSize( rSize ); - - // #i19065# Negative sizes have mirror semantics on - // OutputDevice. BitmapEx and co. have no idea about that, so - // perform that _before_ doing anything with aBitmapEx. - ULONG nMirrorFlags(BMP_MIRROR_NONE); - if( aSize.Width() < 0 ) - { - aSize.Width() *= -1; - aPoint.X() -= aSize.Width(); - nMirrorFlags |= BMP_MIRROR_HORZ; - } - if( aSize.Height() < 0 ) - { - aSize.Height() *= -1; - aPoint.Y() -= aSize.Height(); - nMirrorFlags |= BMP_MIRROR_VERT; - } - - if( nMirrorFlags != BMP_MIRROR_NONE ) - { - aBitmapEx.Mirror( nMirrorFlags ); - } - if ( mbReduceImageResolution ) - { - // do downsampling if neccessary - const Size aDstSizeTwip( rDummyVDev.PixelToLogic( rDummyVDev.LogicToPixel( aSize ), MAP_TWIP ) ); - const Size aBmpSize( aBitmapEx.GetSizePixel() ); - const double fBmpPixelX = aBmpSize.Width(); - const double fBmpPixelY = aBmpSize.Height(); - const double fMaxPixelX = aDstSizeTwip.Width() * mnMaxImageResolution / 1440.0; - const double fMaxPixelY = aDstSizeTwip.Height() * mnMaxImageResolution / 1440.0; - - // check, if the bitmap DPI exceeds the maximum DPI (allow 4 pixel rounding tolerance) - if( ( ( fBmpPixelX > ( fMaxPixelX + 4 ) ) || - ( fBmpPixelY > ( fMaxPixelY + 4 ) ) ) && - ( fBmpPixelY > 0.0 ) && ( fMaxPixelY > 0.0 ) ) - { - // do scaling - Size aNewBmpSize; - const double fBmpWH = fBmpPixelX / fBmpPixelY; - const double fMaxWH = fMaxPixelX / fMaxPixelY; - - if( fBmpWH < fMaxWH ) - { - aNewBmpSize.Width() = FRound( fMaxPixelY * fBmpWH ); - aNewBmpSize.Height() = FRound( fMaxPixelY ); - } - else if( fBmpWH > 0.0 ) - { - aNewBmpSize.Width() = FRound( fMaxPixelX ); - aNewBmpSize.Height() = FRound( fMaxPixelX / fBmpWH); - } - if( aNewBmpSize.Width() && aNewBmpSize.Height() ) - aBitmapEx.Scale( aNewBmpSize ); - else - aBitmapEx.SetEmpty(); - } - } - - const Size aSizePixel( aBitmapEx.GetSizePixel() ); - if ( aSizePixel.Width() && aSizePixel.Height() ) - { - sal_Bool bUseJPGCompression = !mbUseLosslessCompression; - if ( ( aSizePixel.Width() < 32 ) || ( aSizePixel.Height() < 32 ) ) - bUseJPGCompression = sal_False; - - SvMemoryStream aStrm; - Bitmap aMask; - - bool bTrueColorJPG = true; - if ( bUseJPGCompression ) - { - sal_uInt32 nZippedFileSize; // sj: we will calculate the filesize of a zipped bitmap - { // to determine if jpeg compression is usefull - SvMemoryStream aTemp; - aTemp.SetCompressMode( aTemp.GetCompressMode() | COMPRESSMODE_ZBITMAP ); - aTemp.SetVersion( SOFFICE_FILEFORMAT_40 ); // sj: up from version 40 our bitmap stream operator - aTemp << aBitmapEx; // is capable of zlib stream compression - aTemp.Seek( STREAM_SEEK_TO_END ); - nZippedFileSize = aTemp.Tell(); - } - if ( aBitmapEx.IsTransparent() ) - { - if ( aBitmapEx.IsAlpha() ) - aMask = aBitmapEx.GetAlpha().GetBitmap(); - else - aMask = aBitmapEx.GetMask(); - } - GraphicFilter aGraphicFilter; - Graphic aGraphic( aBitmapEx.GetBitmap() ); - sal_uInt16 nFormatName = aGraphicFilter.GetExportFormatNumberForShortName( OUString( RTL_CONSTASCII_USTRINGPARAM( "JPG" ) ) ); - sal_Int32 nColorMode = 0; - - Sequence< PropertyValue > aFilterData( 2 ); - aFilterData[ 0 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Quality" ) ); - aFilterData[ 0 ].Value <<= mnQuality; - aFilterData[ 1 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ColorMode" ) ); - aFilterData[ 1 ].Value <<= nColorMode; - - /*sal_uInt16 nError =*/ aGraphicFilter.ExportGraphic( aGraphic, String(), aStrm, nFormatName, &aFilterData ); - bTrueColorJPG = ((aGraphicFilter.GetExportGraphicHint() & GRFILTER_OUTHINT_GREY) == 0); - aStrm.Seek( STREAM_SEEK_TO_END ); - if ( aStrm.Tell() > nZippedFileSize ) - bUseJPGCompression = sal_False; - } - if ( bUseJPGCompression ) - rWriter.DrawJPGBitmap( aStrm, bTrueColorJPG, aSizePixel, Rectangle( aPoint, aSize ), aMask ); - else if ( aBitmapEx.IsTransparent() ) - rWriter.DrawBitmapEx( aPoint, aSize, aBitmapEx ); - else - rWriter.DrawBitmap( aPoint, aSize, aBitmapEx.GetBitmap() ); - } - } -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |