diff --git a/vcl/inc/vcl/gdimtf.hxx b/vcl/inc/vcl/gdimtf.hxx index 636fc4a979f3..5660bb139f3b 100644 --- a/vcl/inc/vcl/gdimtf.hxx +++ b/vcl/inc/vcl/gdimtf.hxx @@ -135,6 +135,7 @@ private: const OutputDevice& rMapDev, const PolyPolygon& rPolyPoly, const Gradient& rGrad ); + SAL_DLLPRIVATE bool ImplPlayWithRenderer( OutputDevice* pOut, const Point& rPos, Size rDestSize ); //#endif // __PRIVATE diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx index d36a18a1afba..8f0f7abfdf19 100644 --- a/vcl/source/gdi/gdimtf.cxx +++ b/vcl/source/gdi/gdimtf.cxx @@ -35,12 +35,24 @@ #include #include #include -#ifndef _SV_CVTSVM_HXX #include -#endif #include +#include +#include +#include +#include #include #include +#include +#include + +#include +#include +#include +#include +#include + +using namespace com::sun::star; // ----------- // - Defines - @@ -475,6 +487,76 @@ void GDIMetaFile::Play( OutputDevice* pOut, ULONG nPos ) // ------------------------------------------------------------------------ +bool GDIMetaFile::ImplPlayWithRenderer( OutputDevice* pOut, const Point& rPos, Size rDestSize ) +{ + const Window* win = dynamic_cast ( pOut ); + + if (!win) + win = Application::GetActiveTopWindow(); + if (!win) + win = Application::GetFirstTopLevelWindow(); + + if (win) { + const uno::Reference& xCanvas = win->GetCanvas (); + Size aSize (rDestSize.Width () + 1, rDestSize.Height () + 1); + const uno::Reference& xBitmap = xCanvas->getDevice ()->createCompatibleAlphaBitmap (vcl::unotools::integerSize2DFromSize( aSize)); + uno::Reference< lang::XMultiServiceFactory > xFactory = vcl::unohelper::GetMultiServiceFactory(); + if( xFactory.is() && xBitmap.is () ) { + uno::Reference< rendering::XMtfRenderer > xMtfRenderer; + uno::Sequence< uno::Any > args (1); + uno::Reference< rendering::XBitmapCanvas > xBitmapCanvas( xBitmap, uno::UNO_QUERY ); + if( xBitmapCanvas.is() ) { + args[0] = uno::Any( xBitmapCanvas ); + xMtfRenderer.set( xFactory->createInstanceWithArguments( ::rtl::OUString::createFromAscii( "com.sun.star.rendering.MtfRenderer" ), + args ), uno::UNO_QUERY ); + + if( xMtfRenderer.is() ) { + xBitmapCanvas->clear(); + uno::Reference< beans::XFastPropertySet > xMtfFastPropertySet( xMtfRenderer, uno::UNO_QUERY ); + if( xMtfFastPropertySet.is() ) + // set this metafile to the renderer to + // speedup things (instead of copying data to + // sequence of bytes passed to renderer) + xMtfFastPropertySet->setFastPropertyValue( 0, uno::Any( reinterpret_cast( this ) ) ); + + xMtfRenderer->draw( rDestSize.Width(), rDestSize.Height() ); + + uno::Reference< beans::XFastPropertySet > xFastPropertySet( xBitmapCanvas, uno::UNO_QUERY ); + if( xFastPropertySet.get() ) { + // 0 means get BitmapEx + uno::Any aAny = xFastPropertySet->getFastPropertyValue( 0 ); + BitmapEx* pBitmapEx = (BitmapEx*) *reinterpret_cast(aAny.getValue()); + if( pBitmapEx ) { + pOut->DrawBitmapEx( rPos, *pBitmapEx ); + delete pBitmapEx; + return true; + } + } + + SalBitmap* pSalBmp = ImplGetSVData()->mpDefInst->CreateSalBitmap(); + SalBitmap* pSalMask = ImplGetSVData()->mpDefInst->CreateSalBitmap(); + + if( pSalBmp->Create( xBitmapCanvas, aSize ) && pSalMask->Create( xBitmapCanvas, aSize, true ) ) { + Bitmap aBitmap( pSalBmp ); + Bitmap aMask( pSalMask ); + AlphaMask aAlphaMask( aMask ); + BitmapEx aBitmapEx( aBitmap, aAlphaMask ); + pOut->DrawBitmapEx( rPos, aBitmapEx ); + return true; + } + + delete pSalBmp; + delete pSalMask; + } + } + } + } + + return false; +} + +// ------------------------------------------------------------------------ + void GDIMetaFile::Play( OutputDevice* pOut, const Point& rPos, const Size& rSize, ULONG nPos ) { @@ -484,9 +566,13 @@ void GDIMetaFile::Play( OutputDevice* pOut, const Point& rPos, if( aDestSize.Width() && aDestSize.Height() ) { - Size aTmpPrefSize( pOut->LogicToPixel( GetPrefSize(), aDrawMap ) ); GDIMetaFile* pMtf = pOut->GetConnectMetaFile(); + if( !pMtf && ImplPlayWithRenderer( pOut, rPos, aDestSize ) ) + return; + + Size aTmpPrefSize( pOut->LogicToPixel( GetPrefSize(), aDrawMap ) ); + if( !aTmpPrefSize.Width() ) aTmpPrefSize.Width() = aDestSize.Width(); diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx index 94f07b8f17d1..1102569d0844 100644 --- a/vcl/source/gdi/metaact.cxx +++ b/vcl/source/gdi/metaact.cxx @@ -4093,6 +4093,7 @@ void MetaCommentAction::Move( long nXMove, long nYMove ) // SJ: 25.07.06 #i56656# we are not able to mirrorcertain kind of // comments properly, especially the XPATHSTROKE and XPATHFILL lead to // problems, so it is better to remove these comments when mirroring +// FIXME: fake comment to apply the next hunk in the right location void MetaCommentAction::Scale( double fXScale, double fYScale ) { if ( ( fXScale != 1.0 ) || ( fYScale != 1.0 ) ) @@ -4126,6 +4127,32 @@ void MetaCommentAction::Scale( double fXScale, double fYScale ) } delete[] mpData; ImplInitDynamicData( static_cast( aDest.GetData() ), aDest.Tell() ); + } else if( maComment.Equals( "EMF_PLUS_HEADER_INFO" ) ) { + SvMemoryStream aMemStm( (void*)mpData, mnDataSize, STREAM_READ ); + SvMemoryStream aDest; + + sal_Int32 nLeft, nRight, nTop, nBottom; + sal_Int32 nPixX, nPixY, nMillX, nMillY; + float m11, m12, m21, m22, mdx, mdy; + + // read data + aMemStm >> nLeft >> nTop >> nRight >> nBottom; + aMemStm >> nPixX >> nPixY >> nMillX >> nMillY; + aMemStm >> m11 >> m12 >> m21 >> m22 >> mdx >> mdy; + + // add scale to the transformation + m11 *= fXScale; + m12 *= fXScale; + m22 *= fYScale; + m21 *= fYScale; + + // prepare new data + aDest << nLeft << nTop << nRight << nBottom; + aDest << nPixX << nPixY << nMillX << nMillY; + aDest << m11 << m12 << m21 << m22 << mdx << mdy; + + // save them + ImplInitDynamicData( static_cast( aDest.GetData() ), aDest.Tell() ); } } }