You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by al...@apache.org on 2013/01/23 15:27:51 UTC

svn commit: r1437407 [2/3] - in /openoffice/trunk: ./ main/canvas/source/vcl/ main/drawinglayer/ main/drawinglayer/source/processor2d/ main/officecfg/registry/schema/org/openoffice/Office/ main/svx/source/sdr/contact/ main/svx/source/svdraw/ main/vcl/a...

Modified: openoffice/trunk/main/vcl/source/gdi/outdev2.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/source/gdi/outdev2.cxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/source/gdi/outdev2.cxx (original)
+++ openoffice/trunk/main/vcl/source/gdi/outdev2.cxx Wed Jan 23 14:27:50 2013
@@ -19,13 +19,10 @@
  * 
  *************************************************************/
 
-
-
 // MARKER(update_precomp.py): autogen include statement, do not remove
 #include "precompiled_vcl.hxx"
 
 #include <tools/debug.hxx>
-
 #include <vcl/bitmap.hxx>
 #include <vcl/bitmapex.hxx>
 #include <vcl/window.hxx>
@@ -36,7 +33,6 @@
 #include <vcl/outdev.hxx>
 #include <vcl/window.hxx>
 #include <vcl/image.hxx>
-
 #include <bmpfast.hxx>
 #include <salbmp.hxx>
 #include <salgdi.hxx>
@@ -46,6 +42,7 @@
 #include <outdev.h>
 #include <window.h>
 #include <outdata.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
 
 #define BAND_MAX_SIZE 512000
 
@@ -75,8 +72,6 @@ DBG_NAMEEX( OutputDevice )
 		return; 							\
 }
 
-#define TwoRect 	SalTwoRect
-
 // -------------
 // - externals -
 // -------------
@@ -89,7 +84,7 @@ extern sal_uLong nVCLLut[ 256 ];
 
 // =======================================================================
 
-sal_uLong ImplAdjustTwoRect( TwoRect& rTwoRect, const Size& rSizePix )
+sal_uLong ImplAdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix )
 {
 	sal_uLong nMirrFlags = 0;
 
@@ -148,12 +143,11 @@ sal_uLong ImplAdjustTwoRect( TwoRect& rT
 
 // =======================================================================
 
-void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, void* pVoidPosAry )
+void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, SalTwoRect& rPosAry )
 {
-	TwoRect*			pPosAry = (TwoRect*)pVoidPosAry;
 	SalGraphics*		pGraphics2;
 
-	if ( pPosAry->mnSrcWidth && pPosAry->mnSrcHeight && pPosAry->mnDestWidth && pPosAry->mnDestHeight )
+	if ( rPosAry.mnSrcWidth && rPosAry.mnSrcHeight && rPosAry.mnDestWidth && rPosAry.mnDestHeight )
 	{
 		if ( this == pSrcDev )
 			pGraphics2 = NULL;
@@ -196,25 +190,25 @@ void OutputDevice::ImplDrawOutDevDirect(
         // #102532# Offset only has to be pseudo window offset
 		Rectangle	aSrcOutRect( Point( pSrcDev->mnOutOffX, pSrcDev->mnOutOffY ),
 								 Size( pSrcDev->mnOutWidth, pSrcDev->mnOutHeight ) );
-		Rectangle	aSrcRect( Point( pPosAry->mnSrcX, pPosAry->mnSrcY ),
-							  Size( pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ) );
+		Rectangle	aSrcRect( Point( rPosAry.mnSrcX, rPosAry.mnSrcY ),
+							  Size( rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ) );
 		const long	nOldRight = aSrcRect.Right();
 		const long	nOldBottom = aSrcRect.Bottom();
 
 		if ( !aSrcRect.Intersection( aSrcOutRect ).IsEmpty() )
 		{
-			if ( (pPosAry->mnSrcX+pPosAry->mnSrcWidth-1) > aSrcOutRect.Right() )
+			if ( (rPosAry.mnSrcX+rPosAry.mnSrcWidth-1) > aSrcOutRect.Right() )
 			{
-				const long nOldWidth = pPosAry->mnSrcWidth;
-				pPosAry->mnSrcWidth -= (nOldRight - aSrcRect.Right());
-				pPosAry->mnDestWidth = pPosAry->mnDestWidth * pPosAry->mnSrcWidth / nOldWidth;
+				const long nOldWidth = rPosAry.mnSrcWidth;
+				rPosAry.mnSrcWidth -= (nOldRight - aSrcRect.Right());
+				rPosAry.mnDestWidth = rPosAry.mnDestWidth * rPosAry.mnSrcWidth / nOldWidth;
 			}
 
-			if ( (pPosAry->mnSrcY+pPosAry->mnSrcHeight-1) > aSrcOutRect.Bottom() )
+			if ( (rPosAry.mnSrcY+rPosAry.mnSrcHeight-1) > aSrcOutRect.Bottom() )
 			{
-				const long nOldHeight = pPosAry->mnSrcHeight;
-				pPosAry->mnSrcHeight -= (nOldBottom - aSrcRect.Bottom());
-				pPosAry->mnDestHeight = pPosAry->mnDestHeight * pPosAry->mnSrcHeight / nOldHeight;
+				const long nOldHeight = rPosAry.mnSrcHeight;
+				rPosAry.mnSrcHeight -= (nOldBottom - aSrcRect.Bottom());
+				rPosAry.mnDestHeight = rPosAry.mnDestHeight * rPosAry.mnSrcHeight / nOldHeight;
 			}
 
             // --- RTL --- if this is no window, but pSrcDev is a window
@@ -223,12 +217,12 @@ void OutputDevice::ImplDrawOutDevDirect(
             // mirroring is performed here
             if( (GetOutDevType() != OUTDEV_WINDOW) && pGraphics2 && (pGraphics2->GetLayout() & SAL_LAYOUT_BIDI_RTL) )
             {
-		        SalTwoRect pPosAry2 = *pPosAry;
-			    pGraphics2->mirror( pPosAry2.mnSrcX, pPosAry2.mnSrcWidth, pSrcDev ); 
-			    mpGraphics->CopyBits( &pPosAry2, pGraphics2, this, pSrcDev );
+		        SalTwoRect aPosAry2 = rPosAry;
+			    pGraphics2->mirror( aPosAry2.mnSrcX, aPosAry2.mnSrcWidth, pSrcDev ); 
+			    mpGraphics->CopyBits( aPosAry2, pGraphics2, this, pSrcDev );
             }
             else
-			    mpGraphics->CopyBits( pPosAry, pGraphics2, this, pSrcDev );
+			    mpGraphics->CopyBits( rPosAry, pGraphics2, this, pSrcDev );
 		}
 	}
 }
@@ -262,7 +256,7 @@ void OutputDevice::DrawOutDev( const Poi
 
 	OUTDEV_INIT();
 
-	TwoRect aPosAry;
+	SalTwoRect aPosAry;
 	aPosAry.mnSrcWidth	 = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
 	aPosAry.mnSrcHeight  = ImplLogicHeightToDevicePixel( rSrcSize.Height() );
 	aPosAry.mnDestWidth  = ImplLogicWidthToDevicePixel( rDestSize.Width() );
@@ -298,7 +292,7 @@ void OutputDevice::DrawOutDev( const Poi
 				aPosAry.mnDestHeight = aPosAry.mnDestHeight*aPosAry.mnSrcHeight/nOldHeight;
 			}
 
-			mpGraphics->CopyBits( &aPosAry, NULL, this, NULL );
+			mpGraphics->CopyBits( aPosAry, NULL, this, NULL );
 		}
 	}
 
@@ -335,7 +329,7 @@ void OutputDevice::DrawOutDev( const Poi
 
 	OUTDEV_INIT();
 
-	TwoRect aPosAry;
+	SalTwoRect aPosAry;
 	aPosAry.mnSrcX		 = rOutDev.ImplLogicXToDevicePixel( rSrcPt.X() );
 	aPosAry.mnSrcY		 = rOutDev.ImplLogicYToDevicePixel( rSrcPt.Y() );
 	aPosAry.mnSrcWidth	 = rOutDev.ImplLogicWidthToDevicePixel( rSrcSize.Width() );
@@ -358,7 +352,7 @@ void OutputDevice::DrawOutDev( const Poi
         }
         else
         {
-            ImplDrawOutDevDirect( &rOutDev, &aPosAry );
+            ImplDrawOutDevDirect( &rOutDev, aPosAry );
 
             // #i32109#: make destination rectangle opaque - source has no alpha
             mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) );
@@ -374,7 +368,7 @@ void OutputDevice::DrawOutDev( const Poi
         else
         {
             // no alpha at all, neither in source nor destination device
-            ImplDrawOutDevDirect( &rOutDev, &aPosAry );
+            ImplDrawOutDevDirect( &rOutDev, aPosAry );
         }
     }
 }
@@ -397,7 +391,7 @@ void OutputDevice::CopyArea( const Point
 
 	OUTDEV_INIT();
 
-	TwoRect aPosAry;
+	SalTwoRect aPosAry;
 	aPosAry.mnSrcWidth	 = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
 	aPosAry.mnSrcHeight  = ImplLogicHeightToDevicePixel( rSrcSize.Height() );
 
@@ -439,7 +433,7 @@ void OutputDevice::CopyArea( const Point
 			{
 				aPosAry.mnDestWidth  = aPosAry.mnSrcWidth;
 				aPosAry.mnDestHeight = aPosAry.mnSrcHeight;
-				mpGraphics->CopyBits( &aPosAry, NULL, this, NULL );
+				mpGraphics->CopyBits( aPosAry, NULL, this, NULL );
 			}
 		}
 	}
@@ -479,7 +473,7 @@ void OutputDevice::ImplDrawFrameDev( con
 	else
 		ImplSelectClipRegion( rRegion );
 
-	TwoRect aPosAry;
+	SalTwoRect aPosAry;
 	aPosAry.mnSrcX		 = rDevPt.X();
 	aPosAry.mnSrcY		 = rDevPt.Y();
 	aPosAry.mnSrcWidth	 = rDevSize.Width();
@@ -488,7 +482,7 @@ void OutputDevice::ImplDrawFrameDev( con
 	aPosAry.mnDestY 	 = rPt.Y();
 	aPosAry.mnDestWidth  = rDevSize.Width();
 	aPosAry.mnDestHeight = rDevSize.Height();
-	ImplDrawOutDevDirect( &rOutDev, &aPosAry );
+	ImplDrawOutDevDirect( &rOutDev, aPosAry );
 
 	// Dafuer sorgen, das ClipRegion neu berechnet und gesetzt wird
 	mbInitClipRegion = sal_True;
@@ -576,16 +570,18 @@ void OutputDevice::ImplDrawBitmap( const
 {
 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
 
-	Bitmap aBmp( rBitmap );
-
 	if ( ( mnDrawMode & DRAWMODE_NOBITMAP ) )
 		return;
-	else if ( ROP_INVERT == meRasterOp )
+
+    if ( ROP_INVERT == meRasterOp )
 	{
 		DrawRect( Rectangle( rDestPt, rDestSize ) );
 		return;
 	}
-	else if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | 
+	
+	Bitmap aBmp( rBitmap );
+
+    if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | 
 							 DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP ) )
 	{
 		if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) )
@@ -638,7 +634,7 @@ void OutputDevice::ImplDrawBitmap( const
 
 	if( !aBmp.IsEmpty() )
 	{
-		TwoRect aPosAry;
+		SalTwoRect aPosAry;
 
 		aPosAry.mnSrcX = rSrcPtPixel.X();
 		aPosAry.mnSrcY = rSrcPtPixel.Y();
@@ -667,6 +663,11 @@ void OutputDevice::ImplDrawBitmap( const
             * that the destination rectangle will overlap the device but only
             * be reasonably (say factor 2) larger than the device itself.
             */
+
+            // not needed for win32, it uses GdiPlus and is able to do everything without
+            // internally scaling the bitmap
+#ifndef WIN32 
+
             if( aPosAry.mnDestWidth > 2048 || aPosAry.mnDestHeight > 2048 )
             {
                  if( meOutDevType == OUTDEV_WINDOW ||
@@ -720,9 +721,12 @@ void OutputDevice::ImplDrawBitmap( const
                     }
                 }
             }
+#endif
 
             if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
-                mpGraphics->DrawBitmap( &aPosAry, *aBmp.ImplGetImpBitmap()->ImplGetSalBitmap(), this );
+            {
+                mpGraphics->DrawBitmap( aPosAry, *aBmp.ImplGetImpBitmap()->ImplGetSalBitmap(), this );
+            }
 		}
 	}
 }
@@ -738,7 +742,9 @@ void OutputDevice::DrawBitmapEx( const P
         return;
 
 	if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
+    {
 		DrawBitmap( rDestPt, rBitmapEx.GetBitmap() );
+    }
 	else
 	{
 		const Size aSizePix( rBitmapEx.GetSizePixel() );
@@ -757,9 +763,13 @@ void OutputDevice::DrawBitmapEx( const P
         return;
 
 	if ( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
+    {
 		DrawBitmap( rDestPt, rDestSize, rBitmapEx.GetBitmap() );
+    }
 	else
+    {
 		ImplDrawBitmapEx( rDestPt, rDestSize, Point(), rBitmapEx.GetSizePixel(), rBitmapEx, META_BMPEXSCALE_ACTION );
+    }
 }
 
 // ------------------------------------------------------------------
@@ -774,9 +784,117 @@ void OutputDevice::DrawBitmapEx( const P
         return;
 
 	if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
+    {
 		DrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx.GetBitmap() );
+    }
 	else
+    {
 		ImplDrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx, META_BMPEXSCALEPART_ACTION );
+    }
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawTransformedBitmapEx(
+    const basegfx::B2DHomMatrix& rTransformation,
+    const BitmapEx& rBitmapEx)
+{
+	DBG_TRACE( "OutputDevice::DrawBitmapEx( Point, Size )" );
+
+    if( ImplIsRecordLayout() )
+        return;
+
+    if(rBitmapEx.IsEmpty())
+        return;
+
+    if ( mnDrawMode & DRAWMODE_NOBITMAP )
+        return;
+
+    // decompose matrix to check rotation and shear
+    basegfx::B2DVector aScale, aTranslate;
+    double fRotate, fShearX;
+    rTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
+    const bool bRotated(!basegfx::fTools::equalZero(fRotate));
+    const bool bSheared(!basegfx::fTools::equalZero(fShearX));
+    const bool bMirroredX(basegfx::fTools::less(aScale.getX(), 0.0));
+    const bool bMirroredY(basegfx::fTools::less(aScale.getY(), 0.0));
+
+    if(!bRotated && !bSheared && !bMirroredX && !bMirroredY)
+    {
+        // with no rotation, shear or mirroring it can be mapped to DrawBitmapEx
+        // do *not* execute the mirroring here, it's done in the fallback
+        const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY()));
+        const Size aDestSize(basegfx::fround(aScale.getX()), basegfx::fround(aScale.getY()));
+
+        DrawBitmapEx(aDestPt, aDestSize, rBitmapEx);
+        return;
+    }
+
+    // we have rotation,shear or mirror, check if some crazy mode needs the
+    // created transformed bitmap
+    const bool bInvert(ROP_INVERT == meRasterOp);
+    const bool bBitmapChangedColor(mnDrawMode & (DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP));
+    const bool bMetafile(mpMetaFile);
+    const bool bPrinter(OUTDEV_PRINTER == meOutDevType);
+    bool bDone(false);
+    const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation);
+    const bool bTryDirectPaint(!bInvert && !bBitmapChangedColor && !bMetafile && !bPrinter);
+
+    if(bTryDirectPaint)
+    {
+        // try to paint directly
+        const basegfx::B2DPoint aNull(aFullTransform * basegfx::B2DPoint(0.0, 0.0));
+        const basegfx::B2DPoint aTopX(aFullTransform * basegfx::B2DPoint(1.0, 0.0));
+        const basegfx::B2DPoint aTopY(aFullTransform * basegfx::B2DPoint(0.0, 1.0));
+        SalBitmap* pSalSrcBmp = rBitmapEx.GetBitmap().ImplGetImpBitmap()->ImplGetSalBitmap();
+        SalBitmap* pSalAlphaBmp = 0;
+
+        if(rBitmapEx.IsTransparent())
+        {
+            if(rBitmapEx.IsAlpha())
+            {
+                pSalAlphaBmp = rBitmapEx.GetAlpha().ImplGetImpBitmap()->ImplGetSalBitmap();
+            }
+            else
+            {
+                pSalAlphaBmp = rBitmapEx.GetMask().ImplGetImpBitmap()->ImplGetSalBitmap();
+            }
+        }
+
+        bDone = mpGraphics->DrawTransformedBitmap(
+            aNull, 
+            aTopX, 
+            aTopY,
+            *pSalSrcBmp,
+            pSalAlphaBmp,
+            this);
+    }
+
+    if(!bDone)
+    {
+        // take the fallback when no rotate and shear, but mirror (else we would have done this above)
+        if(!bRotated && !bSheared)
+        {
+            // with no rotation or shear it can be mapped to DrawBitmapEx
+            // do *not* execute the mirroring here, it's done in the fallback
+            const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY()));
+            const Size aDestSize(basegfx::fround(aScale.getX()), basegfx::fround(aScale.getY()));
+
+            DrawBitmapEx(aDestPt, aDestSize, rBitmapEx);
+            return;
+        }
+
+        // fallback; create transformed bitmap the hard way (back-transform
+        // the pixels) and paint
+        basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0);
+        const double fMaximumArea(bMetafile ? 800000.0 : 200000.0);
+        const BitmapEx aTransformed(rBitmapEx.getTransformed(aFullTransform, fMaximumArea));
+        aTargetRange.transform(rTransformation);
+        const Point aDestPt(basegfx::fround(aTargetRange.getMinX()), basegfx::fround(aTargetRange.getMinY()));
+        const Size aDestSize(basegfx::fround(aTargetRange.getWidth()), basegfx::fround(aTargetRange.getHeight()));
+
+        DrawBitmapEx(aDestPt, aDestSize, aTransformed);
+    }
 }
 
 // ------------------------------------------------------------------
@@ -786,17 +904,20 @@ void OutputDevice::ImplDrawBitmapEx( con
 									 const BitmapEx& rBitmapEx, const sal_uLong nAction )
 {
 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
-
-	BitmapEx aBmpEx( rBitmapEx );
+    OSL_ENSURE(TRANSPARENT_NONE != rBitmapEx.GetTransparentType(), "ImplDrawBitmapEx not needed, no transparency in BitmapEx (!)");
 
 	if ( mnDrawMode & DRAWMODE_NOBITMAP )
 		return;
-	else if ( ROP_INVERT == meRasterOp )
+
+    if ( ROP_INVERT == meRasterOp )
 	{
 		DrawRect( Rectangle( rDestPt, rDestSize ) );
 		return;
 	}
-	else if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | 
+
+	BitmapEx aBmpEx( rBitmapEx );
+
+    if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | 
 							 DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP ) )
 	{
 		if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) )
@@ -875,9 +996,11 @@ void OutputDevice::ImplDrawBitmapEx( con
             aBmp.Replace( aMask, Color( COL_WHITE ) );
             ImplPrintTransparent( aBmp, aMask, rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
         }
-	    return;
+	
+        return;
 	}
-	else if( aBmpEx.IsAlpha() )
+
+    if(aBmpEx.IsAlpha())
 	{
 		ImplDrawAlpha( aBmpEx.GetBitmap(), aBmpEx.GetAlpha(), rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
 		return;
@@ -885,7 +1008,7 @@ void OutputDevice::ImplDrawBitmapEx( con
 
 	if( !( !aBmpEx ) )
 	{
-		TwoRect aPosAry;
+		SalTwoRect aPosAry;
 
 		aPosAry.mnSrcX = rSrcPtPixel.X();
 		aPosAry.mnSrcY = rSrcPtPixel.Y();
@@ -904,70 +1027,92 @@ void OutputDevice::ImplDrawBitmapEx( con
 			if( nMirrFlags )
 				aBmpEx.Mirror( nMirrFlags );
 
-			const ImpBitmap* pImpBmp = aBmpEx.ImplGetBitmapImpBitmap();
+            const SalBitmap* pSalSrcBmp = aBmpEx.ImplGetBitmapImpBitmap()->ImplGetSalBitmap();
 			const ImpBitmap* pMaskBmp = aBmpEx.ImplGetMaskImpBitmap();
 
 			if ( pMaskBmp )
             {
-                // #4919452# reduce operation area to bounds of
-                // cliprect. since masked transparency involves
-                // creation of a large vdev and copying the screen
-                // content into that (slooow read from framebuffer),
-                // that should considerably increase performance for
-                // large bitmaps and small clippings.
-
-                // Note that this optimisation is a workaround for a
-                // Writer peculiarity, namely, to decompose background
-                // graphics into myriads of disjunct, tiny
-                // rectangles. That otherwise kills us here, since for
-                // transparent output, SAL always prepares the whole
-                // bitmap, if aPosAry contains the whole bitmap (and
-                // it's _not_ to blame for that).
-
-                // Note the call to ImplPixelToDevicePixel(), since
-                // aPosAry already contains the mnOutOff-offsets, they
-                // also have to be applied to the region
-                Rectangle aClipRegionBounds( ImplPixelToDevicePixel(maRegion).GetBoundRect() );
-
-                // TODO: Also respect scaling (that's a bit tricky,
-                // since the source points have to move fractional
-                // amounts (which is not possible, thus has to be
-                // emulated by increases copy area)
-                // const double nScaleX( aPosAry.mnDestWidth / aPosAry.mnSrcWidth );
-                // const double nScaleY( aPosAry.mnDestHeight / aPosAry.mnSrcHeight );
-
-                // for now, only identity scales allowed
-                if( !aClipRegionBounds.IsEmpty() &&
-                    aPosAry.mnDestWidth == aPosAry.mnSrcWidth &&
-                    aPosAry.mnDestHeight == aPosAry.mnSrcHeight )
+                SalBitmap* pSalAlphaBmp = pMaskBmp->ImplGetSalBitmap();
+                bool bTryDirectPaint(pSalSrcBmp && pSalAlphaBmp);
+
+                if(bTryDirectPaint)
                 {
-                    // now intersect dest rect with clip region
-                    aClipRegionBounds.Intersection( Rectangle( aPosAry.mnDestX, 
-                                                               aPosAry.mnDestY,
-                                                               aPosAry.mnDestX + aPosAry.mnDestWidth - 1,
-                                                               aPosAry.mnDestY + aPosAry.mnDestHeight - 1 ) );
-
-                    // Note: I could theoretically optimize away the
-                    // DrawBitmap below, if the region is empty
-                    // here. Unfortunately, cannot rule out that
-                    // somebody relies on the side effects.
-                    if( !aClipRegionBounds.IsEmpty() )
+                    // only paint direct when no scaling and no MapMode, else the
+                    // more expensive conversions may be done for short-time Bitmap/BitmapEx
+                    // used for buffering only
+                    if(!IsMapMode() && aPosAry.mnSrcWidth == aPosAry.mnDestWidth && aPosAry.mnSrcHeight == aPosAry.mnDestHeight)
                     {
-                        aPosAry.mnSrcX += aClipRegionBounds.Left() - aPosAry.mnDestX;
-                        aPosAry.mnSrcY += aClipRegionBounds.Top() - aPosAry.mnDestY;
-                        aPosAry.mnSrcWidth = aClipRegionBounds.GetWidth();
-                        aPosAry.mnSrcHeight = aClipRegionBounds.GetHeight();
-                        
-                        aPosAry.mnDestX = aClipRegionBounds.Left();
-                        aPosAry.mnDestY = aClipRegionBounds.Top();
-                        aPosAry.mnDestWidth = aClipRegionBounds.GetWidth();
-                        aPosAry.mnDestHeight = aClipRegionBounds.GetHeight();
+                        bTryDirectPaint = false;
                     }
                 }
 
-				mpGraphics->DrawBitmap( &aPosAry, *pImpBmp->ImplGetSalBitmap(), 
-                                        *pMaskBmp->ImplGetSalBitmap(), 
-                                        this );
+                if(bTryDirectPaint && mpGraphics->DrawAlphaBitmap(aPosAry, *pSalSrcBmp, *pSalAlphaBmp, this))
+                {
+                    // tried to paint as alpha directly. If tis worked, we are done (except
+                    // alpha, see below)
+                }
+                else
+                {
+                    // #4919452# reduce operation area to bounds of
+                    // cliprect. since masked transparency involves
+                    // creation of a large vdev and copying the screen
+                    // content into that (slooow read from framebuffer),
+                    // that should considerably increase performance for
+                    // large bitmaps and small clippings.
+
+                    // Note that this optimisation is a workaround for a
+                    // Writer peculiarity, namely, to decompose background
+                    // graphics into myriads of disjunct, tiny
+                    // rectangles. That otherwise kills us here, since for
+                    // transparent output, SAL always prepares the whole
+                    // bitmap, if aPosAry contains the whole bitmap (and
+                    // it's _not_ to blame for that).
+
+                    // Note the call to ImplPixelToDevicePixel(), since
+                    // aPosAry already contains the mnOutOff-offsets, they
+                    // also have to be applied to the region
+                    Rectangle aClipRegionBounds( ImplPixelToDevicePixel(maRegion).GetBoundRect() );
+
+                    // TODO: Also respect scaling (that's a bit tricky,
+                    // since the source points have to move fractional
+                    // amounts (which is not possible, thus has to be
+                    // emulated by increases copy area)
+                    // const double nScaleX( aPosAry.mnDestWidth / aPosAry.mnSrcWidth );
+                    // const double nScaleY( aPosAry.mnDestHeight / aPosAry.mnSrcHeight );
+
+                    // for now, only identity scales allowed
+                    if( !aClipRegionBounds.IsEmpty() &&
+                        aPosAry.mnDestWidth == aPosAry.mnSrcWidth &&
+                        aPosAry.mnDestHeight == aPosAry.mnSrcHeight )
+                    {
+                        // now intersect dest rect with clip region
+                        aClipRegionBounds.Intersection( Rectangle( aPosAry.mnDestX, 
+                                                                   aPosAry.mnDestY,
+                                                                   aPosAry.mnDestX + aPosAry.mnDestWidth - 1,
+                                                                   aPosAry.mnDestY + aPosAry.mnDestHeight - 1 ) );
+
+                        // Note: I could theoretically optimize away the
+                        // DrawBitmap below, if the region is empty
+                        // here. Unfortunately, cannot rule out that
+                        // somebody relies on the side effects.
+                        if( !aClipRegionBounds.IsEmpty() )
+                        {
+                            aPosAry.mnSrcX += aClipRegionBounds.Left() - aPosAry.mnDestX;
+                            aPosAry.mnSrcY += aClipRegionBounds.Top() - aPosAry.mnDestY;
+                            aPosAry.mnSrcWidth = aClipRegionBounds.GetWidth();
+                            aPosAry.mnSrcHeight = aClipRegionBounds.GetHeight();
+                        
+                            aPosAry.mnDestX = aClipRegionBounds.Left();
+                            aPosAry.mnDestY = aClipRegionBounds.Top();
+                            aPosAry.mnDestWidth = aClipRegionBounds.GetWidth();
+                            aPosAry.mnDestHeight = aClipRegionBounds.GetHeight();
+                        }
+                    }
+
+                    mpGraphics->DrawBitmap( aPosAry, *pSalSrcBmp, 
+                                            *pMaskBmp->ImplGetSalBitmap(), 
+                                            this );
+                }
 
                 // #110958# Paint mask to alpha channel. Luckily, the
                 // black and white representation of the mask maps to
@@ -986,7 +1131,7 @@ void OutputDevice::ImplDrawBitmapEx( con
             }
 			else
             {
-				mpGraphics->DrawBitmap( &aPosAry, *pImpBmp->ImplGetSalBitmap(), this );
+				mpGraphics->DrawBitmap( aPosAry, *pSalSrcBmp, this );
 
                 if( mpAlphaVDev )
                 {
@@ -1132,7 +1277,7 @@ void OutputDevice::ImplDrawMask( const P
 	const ImpBitmap* pImpBmp = rBitmap.ImplGetImpBitmap();
 	if ( pImpBmp )
 	{
-		TwoRect aPosAry;
+		SalTwoRect aPosAry;
 
 		aPosAry.mnSrcX = rSrcPtPixel.X();
 		aPosAry.mnSrcY = rSrcPtPixel.Y();
@@ -1154,11 +1299,11 @@ void OutputDevice::ImplDrawMask( const P
 			{
 				Bitmap aTmp( rBitmap );
 				aTmp.Mirror( nMirrFlags );
-				mpGraphics->DrawMask( &aPosAry, *aTmp.ImplGetImpBitmap()->ImplGetSalBitmap(),
+				mpGraphics->DrawMask( aPosAry, *aTmp.ImplGetImpBitmap()->ImplGetSalBitmap(),
 									  ImplColorToSal( rMaskColor ) , this);
 			}
 			else
-				mpGraphics->DrawMask( &aPosAry, *pImpBmp->ImplGetSalBitmap(),
+				mpGraphics->DrawMask( aPosAry, *pImpBmp->ImplGetSalBitmap(),
 									  ImplColorToSal( rMaskColor ), this );
 
 		}
@@ -1299,7 +1444,7 @@ Bitmap OutputDevice::GetBitmap( const Po
 				{
 					if ( ((OutputDevice*)&aVDev)->mpGraphics || ((OutputDevice*)&aVDev)->ImplGetGraphics() )
 					{
-						TwoRect aPosAry;
+						SalTwoRect aPosAry;
 
 						aPosAry.mnSrcX = nX;
 						aPosAry.mnSrcY = nY;
@@ -1311,7 +1456,7 @@ Bitmap OutputDevice::GetBitmap( const Po
 						aPosAry.mnDestHeight = nHeight;
 
 						if ( (nWidth > 0) && (nHeight > 0) )
-							(((OutputDevice*)&aVDev)->mpGraphics)->CopyBits( &aPosAry, mpGraphics, this, this );
+							(((OutputDevice*)&aVDev)->mpGraphics)->CopyBits( aPosAry, mpGraphics, this, this );
 
 						aBmp = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
 					 }
@@ -1945,7 +2090,22 @@ void OutputDevice::ImplDrawAlpha( const 
         static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
         // #i83087# Naturally, system alpha blending cannot work with
         // separate alpha VDev
-        if( !mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr ) 
+        bool bTryDirectPaint(!mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr);
+
+#ifdef WNT
+        if(bTryDirectPaint)
+        {
+            // only paint direct when no scaling and no MapMode, else the
+            // more expensive conversions may be done for short-time Bitmap/BitmapEx
+            // used for buffering only
+            if(!IsMapMode() && rSrcSizePixel.Width() == aOutSz.Width() && rSrcSizePixel.Height() == aOutSz.Height())
+            {
+                bTryDirectPaint = false;
+            }
+        }
+#endif
+
+        if(bTryDirectPaint) 
         {
             Point aRelPt = aOutPt + Point( mnOutOffX, mnOutOffY );
             SalTwoRect aTR = {

Modified: openoffice/trunk/main/vcl/source/gdi/outmap.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/source/gdi/outmap.cxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/source/gdi/outmap.cxx (original)
+++ openoffice/trunk/main/vcl/source/gdi/outmap.cxx Wed Jan 23 14:27:50 2013
@@ -875,7 +875,7 @@ void OutputDevice::SetMapMode( const Map
         mpAlphaVDev->SetMapMode( rNewMapMode );
 
 	// Ist Default-MapMode, dann bereche nichts
-	sal_Bool bOldMap = mbMap;
+	bool bOldMap = mbMap;
 	mbMap = !rNewMapMode.IsDefault();
 	if ( mbMap )
 	{

Modified: openoffice/trunk/main/vcl/source/gdi/salgdilayout.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/source/gdi/salgdilayout.cxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/source/gdi/salgdilayout.cxx (original)
+++ openoffice/trunk/main/vcl/source/gdi/salgdilayout.cxx Wed Jan 23 14:27:50 2013
@@ -95,6 +95,19 @@ bool SalGraphics::drawAlphaBitmap( const
 
 // ----------------------------------------------------------------------------
 
+bool SalGraphics::drawTransformedBitmap(
+    const basegfx::B2DPoint& rNull,
+    const basegfx::B2DPoint& rX,
+    const basegfx::B2DPoint& rY,
+    const SalBitmap& rSourceBitmap,
+    const SalBitmap* pAlphaBitmap)
+{
+    // here direct support for transformed bitmaps can be impemented
+    return false;
+}
+
+// ----------------------------------------------------------------------------
+
 void SalGraphics::mirror( long& x, const OutputDevice *pOutDev, bool bBack ) const
 {
 	long w;
@@ -583,72 +596,72 @@ void	SalGraphics::CopyArea( long nDestX,
 	}
 	copyArea( nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, nFlags );
 }
-void	SalGraphics::CopyBits( const SalTwoRect* pPosAry,
+void	SalGraphics::CopyBits( const SalTwoRect& rPosAry,
                                SalGraphics* pSrcGraphics, const OutputDevice *pOutDev, const OutputDevice *pSrcOutDev )
 {
 	if( ( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) || 
         (pSrcGraphics && ( (pSrcGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL)  || (pSrcOutDev && pSrcOutDev->IsRTLEnabled()) ) ) )
 	{
-		SalTwoRect pPosAry2 = *pPosAry;
+		SalTwoRect aPosAry2 = rPosAry;
 		if( (pSrcGraphics && (pSrcGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL)) || (pSrcOutDev && pSrcOutDev->IsRTLEnabled()) )
-			mirror( pPosAry2.mnSrcX, pPosAry2.mnSrcWidth, pSrcOutDev ); 
+			mirror( aPosAry2.mnSrcX, aPosAry2.mnSrcWidth, pSrcOutDev ); 
 		if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) 
-			mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); 
-		copyBits( &pPosAry2, pSrcGraphics );
+			mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); 
+		copyBits( aPosAry2, pSrcGraphics );
 	}
 	else
-		copyBits( pPosAry, pSrcGraphics );
+		copyBits( rPosAry, pSrcGraphics );
 }
-void	SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+void	SalGraphics::DrawBitmap( const SalTwoRect& rPosAry,
 									const SalBitmap& rSalBitmap, const OutputDevice *pOutDev )
 {
 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
 	{
-		SalTwoRect pPosAry2 = *pPosAry;
-		mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); 
-		drawBitmap( &pPosAry2, rSalBitmap );
+		SalTwoRect aPosAry2 = rPosAry;
+		mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); 
+		drawBitmap( aPosAry2, rSalBitmap );
 	}
 	else
-		drawBitmap( pPosAry, rSalBitmap );
+		drawBitmap( rPosAry, rSalBitmap );
 }
-void	SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+void	SalGraphics::DrawBitmap( const SalTwoRect& rPosAry,
 									const SalBitmap& rSalBitmap,
 									SalColor nTransparentColor, const OutputDevice *pOutDev )
 {
 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
 	{
-		SalTwoRect pPosAry2 = *pPosAry;
-		mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); 
-		drawBitmap( &pPosAry2, rSalBitmap, nTransparentColor );
+		SalTwoRect aPosAry2 = rPosAry;
+		mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); 
+		drawBitmap( aPosAry2, rSalBitmap, nTransparentColor );
 	}
 	else
-		drawBitmap( pPosAry, rSalBitmap, nTransparentColor );
+		drawBitmap( rPosAry, rSalBitmap, nTransparentColor );
 }
-void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+void SalGraphics::DrawBitmap( const SalTwoRect& rPosAry,
                               const SalBitmap& rSalBitmap,
                               const SalBitmap& rTransparentBitmap, const OutputDevice *pOutDev )
 {
 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
 	{
-		SalTwoRect pPosAry2 = *pPosAry;
-		mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); 
-		drawBitmap( &pPosAry2, rSalBitmap, rTransparentBitmap );
+		SalTwoRect aPosAry2 = rPosAry;
+		mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); 
+		drawBitmap( aPosAry2, rSalBitmap, rTransparentBitmap );
 	}
 	else
-		drawBitmap( pPosAry, rSalBitmap, rTransparentBitmap );
+		drawBitmap( rPosAry, rSalBitmap, rTransparentBitmap );
 }
-void	SalGraphics::DrawMask( const SalTwoRect* pPosAry,
+void	SalGraphics::DrawMask( const SalTwoRect& rPosAry,
 								  const SalBitmap& rSalBitmap,
 								  SalColor nMaskColor, const OutputDevice *pOutDev )
 {
 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
 	{
-		SalTwoRect pPosAry2 = *pPosAry;
-		mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); 
-		drawMask( &pPosAry2, rSalBitmap, nMaskColor );
+		SalTwoRect aPosAry2 = rPosAry;
+		mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); 
+		drawMask( aPosAry2, rSalBitmap, nMaskColor );
 	}
 	else
-		drawMask( pPosAry, rSalBitmap, nMaskColor );
+		drawMask( rPosAry, rSalBitmap, nMaskColor );
 }
 SalBitmap*	SalGraphics::GetBitmap( long nX, long nY, long nWidth, long nHeight, const OutputDevice *pOutDev )
 {
@@ -807,14 +820,40 @@ bool SalGraphics::DrawAlphaBitmap( const
 {
 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
 	{
-		SalTwoRect pPosAry2 = rPosAry;
-		mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); 
-		return drawAlphaBitmap( pPosAry2, rSourceBitmap, rAlphaBitmap );
+		SalTwoRect aPosAry2 = rPosAry;
+		mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); 
+		return drawAlphaBitmap( aPosAry2, rSourceBitmap, rAlphaBitmap );
 	}
 	else
 		return drawAlphaBitmap( rPosAry, rSourceBitmap, rAlphaBitmap );
 }
 
+bool SalGraphics::DrawTransformedBitmap(
+    const basegfx::B2DPoint& rNull,
+    const basegfx::B2DPoint& rX,
+    const basegfx::B2DPoint& rY,
+    const SalBitmap& rSourceBitmap,
+    const SalBitmap* pAlphaBitmap,
+    const OutputDevice* pOutDev)
+{
+    if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
+    {
+        basegfx::B2DPoint aNull(rNull);
+        basegfx::B2DPoint aX(rX);
+        basegfx::B2DPoint aY(rY);
+
+        mirror(aNull, pOutDev);
+        mirror(aX, pOutDev);
+        mirror(aY, pOutDev);
+
+        return drawTransformedBitmap(aNull, aX, aY, rSourceBitmap, pAlphaBitmap);
+    }
+    else
+    {
+        return drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, pAlphaBitmap);
+    }
+}
+
 bool SalGraphics::DrawAlphaRect( long nX, long nY, long nWidth, long nHeight, 
                                  sal_uInt8 nTransparency, const OutputDevice *pOutDev )
 {

Modified: openoffice/trunk/main/vcl/source/gdi/salmisc.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/source/gdi/salmisc.cxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/source/gdi/salmisc.cxx (original)
+++ openoffice/trunk/main/vcl/source/gdi/salmisc.cxx Wed Jan 23 14:27:50 2013
@@ -288,8 +288,9 @@ static void	ImplTCToPAL( const BitmapBuf
 // - StretchAndConvert -
 // ---------------------
 
-BitmapBuffer* StretchAndConvert( const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect, 
-								 sal_uLong nDstBitmapFormat, BitmapPalette* pDstPal, ColorMask* pDstMask )
+BitmapBuffer* StretchAndConvert( 
+    const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect, 
+	sal_uLong nDstBitmapFormat, const BitmapPalette* pDstPal, const ColorMask* pDstMask )
 {
     FncGetPixel		pFncGetPixel;
     FncSetPixel		pFncSetPixel;

Modified: openoffice/trunk/main/vcl/source/gdi/virdev.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/source/gdi/virdev.cxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/source/gdi/virdev.cxx (original)
+++ openoffice/trunk/main/vcl/source/gdi/virdev.cxx Wed Jan 23 14:27:50 2013
@@ -274,7 +274,7 @@ sal_Bool VirtualDevice::ImplSetOutputSiz
 				aPosAry.mnDestWidth  = nWidth;
 				aPosAry.mnDestHeight = nHeight;
 
-				pGraphics->CopyBits( &aPosAry, mpGraphics, this, this );
+				pGraphics->CopyBits( aPosAry, mpGraphics, this, this );
 				pNewVirDev->ReleaseGraphics( pGraphics );
 				ImplReleaseGraphics();
 				pSVData->mpDefInst->DestroyVirtualDevice( mpVirDev );

Modified: openoffice/trunk/main/vcl/unx/generic/gdi/pspgraphics.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/unx/generic/gdi/pspgraphics.cxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/unx/generic/gdi/pspgraphics.cxx (original)
+++ openoffice/trunk/main/vcl/unx/generic/gdi/pspgraphics.cxx Wed Jan 23 14:27:50 2013
@@ -469,7 +469,7 @@ sal_Bool PspGraphics::drawEPS( long nX, 
     return m_pPrinterGfx->DrawEPS( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ), pPtr, nSize );
 }
 
-void PspGraphics::copyBits( const SalTwoRect*,
+void PspGraphics::copyBits( const SalTwoRect&,
                             SalGraphics* )
 {
     DBG_ERROR( "Error: PrinterGfx::CopyBits() not implemented" );
@@ -480,12 +480,12 @@ void PspGraphics::copyArea ( long,long,l
     DBG_ERROR( "Error: PrinterGfx::CopyArea() not implemented" );
 }
 
-void PspGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap )
+void PspGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
 {
-    Rectangle aSrc (Point(pPosAry->mnSrcX, pPosAry->mnSrcY),
-                    Size(pPosAry->mnSrcWidth, pPosAry->mnSrcHeight));
-    Rectangle aDst (Point(pPosAry->mnDestX, pPosAry->mnDestY),
-                    Size(pPosAry->mnDestWidth, pPosAry->mnDestHeight));
+    Rectangle aSrc (Point(rPosAry.mnSrcX, rPosAry.mnSrcY),
+                    Size(rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
+    Rectangle aDst (Point(rPosAry.mnDestX, rPosAry.mnDestY),
+                    Size(rPosAry.mnDestWidth, rPosAry.mnDestHeight));
 
     BitmapBuffer* pBuffer= const_cast<SalBitmap&>(rSalBitmap).AcquireBuffer(sal_True);
 
@@ -495,21 +495,21 @@ void PspGraphics::drawBitmap( const SalT
     const_cast<SalBitmap&>(rSalBitmap).ReleaseBuffer (pBuffer, sal_True);
 }
 
-void PspGraphics::drawBitmap( const SalTwoRect*,
+void PspGraphics::drawBitmap( const SalTwoRect&,
                               const SalBitmap&,
                               const SalBitmap& )
 {
     DBG_ERROR("Error: no PrinterGfx::DrawBitmap() for transparent bitmap");
 }
 
-void PspGraphics::drawBitmap( const SalTwoRect*,
+void PspGraphics::drawBitmap( const SalTwoRect&,
                               const SalBitmap&,
                               SalColor )
 {
     DBG_ERROR("Error: no PrinterGfx::DrawBitmap() for transparent color");
 }
 
-void PspGraphics::drawMask( const SalTwoRect*,
+void PspGraphics::drawMask( const SalTwoRect&,
                             const SalBitmap &,
                             SalColor )
 {
@@ -1493,6 +1493,18 @@ bool PspGraphics::drawAlphaBitmap( const
     return false;
 }
 
+bool PspGraphics::drawTransformedBitmap(
+    const basegfx::B2DPoint& rNull,
+    const basegfx::B2DPoint& rX,
+    const basegfx::B2DPoint& rY,
+    const SalBitmap& rSourceBitmap,
+    const SalBitmap* pAlphaBitmap)
+{
+    // here direct support for transformed bitmaps can be impemented
+    (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
+    return false;
+}
+
 bool PspGraphics::drawAlphaRect( long, long, long, long, sal_uInt8 )
 {
     return false;

Modified: openoffice/trunk/main/vcl/unx/generic/gdi/salgdi2.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/unx/generic/gdi/salgdi2.cxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/unx/generic/gdi/salgdi2.cxx (original)
+++ openoffice/trunk/main/vcl/unx/generic/gdi/salgdi2.cxx Wed Jan 23 14:27:50 2013
@@ -457,17 +457,17 @@ void X11SalGraphics::YieldGraphicsExpose
     } while( aEvent.xgraphicsexpose.count != 0 );
 }
 
-void X11SalGraphics::copyBits( const SalTwoRect *pPosAry,
+void X11SalGraphics::copyBits( const SalTwoRect& rPosAry,
 								  SalGraphics	   *pSSrcGraphics )
 {
     X11SalGraphics* pSrcGraphics = pSSrcGraphics
         ? static_cast<X11SalGraphics*>(pSSrcGraphics)
         : this;
     
-    if( pPosAry->mnSrcWidth <= 0
-        || pPosAry->mnSrcHeight <= 0
-        || pPosAry->mnDestWidth <= 0
-        || pPosAry->mnDestHeight <= 0 )
+    if( rPosAry.mnSrcWidth <= 0
+        || rPosAry.mnSrcHeight <= 0
+        || rPosAry.mnDestWidth <= 0
+        || rPosAry.mnDestHeight <= 0 )
     {
         return;
     }
@@ -500,8 +500,8 @@ void X11SalGraphics::copyBits( const Sal
         n = 0;
     
     if( n == 2
-        && pPosAry->mnSrcWidth	== pPosAry->mnDestWidth
-        && pPosAry->mnSrcHeight == pPosAry->mnDestHeight
+        && rPosAry.mnSrcWidth	== rPosAry.mnDestWidth
+        && rPosAry.mnSrcHeight == rPosAry.mnDestHeight
         )
     {
         // #i60699# Need to generate graphics exposures (to repaint
@@ -519,7 +519,7 @@ void X11SalGraphics::copyBits( const Sal
         {
             Pixmap hPixmap = XCreatePixmap( GetXDisplay(),
                                             pSrcGraphics->GetDrawable(),		// source
-                                            pPosAry->mnSrcWidth, pPosAry->mnSrcHeight,
+                                            rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
                                             pSrcGraphics->GetBitCount() );
 
             pCopyGC = GetDisplay()->GetCopyGC( m_nScreen );
@@ -533,16 +533,16 @@ void X11SalGraphics::copyBits( const Sal
                        pSrcGraphics->GetDrawable(),		// source
                        hPixmap,							// destination
                        pCopyGC,							// no clipping
-                       pPosAry->mnSrcX,     pPosAry->mnSrcY,
-                       pPosAry->mnSrcWidth, pPosAry->mnSrcHeight,
+                       rPosAry.mnSrcX,     rPosAry.mnSrcY,
+                       rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
                        0,    				0 );			// destination
             XCopyArea( GetXDisplay(),
                        hPixmap,								// source
                        GetDrawable(),						// destination
                        GetInvertGC(),		// destination clipping
                        0,				    0,				// source
-                       pPosAry->mnSrcWidth, pPosAry->mnSrcHeight,
-                       pPosAry->mnDestX,    pPosAry->mnDestY );
+                       rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
+                       rPosAry.mnDestX,    rPosAry.mnDestY );
             XFreePixmap( GetXDisplay(), hPixmap );
         }
         else
@@ -558,9 +558,9 @@ void X11SalGraphics::copyBits( const Sal
                        pSrcGraphics->GetDrawable(),		// source
                        GetDrawable(),					// destination
                        pCopyGC,							// destination clipping
-                       pPosAry->mnSrcX,     pPosAry->mnSrcY,
-                       pPosAry->mnSrcWidth, pPosAry->mnSrcHeight,
-                       pPosAry->mnDestX,    pPosAry->mnDestY );
+                       rPosAry.mnSrcX,     rPosAry.mnSrcY,
+                       rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
+                       rPosAry.mnDestX,    rPosAry.mnDestY );
         }
 
         if( bNeedGraphicsExposures )
@@ -578,10 +578,10 @@ void X11SalGraphics::copyBits( const Sal
         // #i60699# No chance to handle graphics exposures - we copy
         // to a temp bitmap first, into which no repaints are
         // technically possible.
-        SalBitmap *pDDB = pSrcGraphics->getBitmap( pPosAry->mnSrcX,
-                                                   pPosAry->mnSrcY,
-                                                   pPosAry->mnSrcWidth,
-                                                   pPosAry->mnSrcHeight );
+        SalBitmap *pDDB = pSrcGraphics->getBitmap( rPosAry.mnSrcX,
+                                                   rPosAry.mnSrcY,
+                                                   rPosAry.mnSrcWidth,
+                                                   rPosAry.mnSrcHeight );
         
         if( !pDDB )
         {
@@ -589,10 +589,10 @@ void X11SalGraphics::copyBits( const Sal
             return;
         }
         
-        SalTwoRect aPosAry( *pPosAry );
+        SalTwoRect aPosAry( rPosAry );
         
         aPosAry.mnSrcX = 0,	aPosAry.mnSrcY = 0;
-        drawBitmap( &aPosAry, *pDDB );
+        drawBitmap( aPosAry, *pDDB );
         
         delete pDDB;
     }
@@ -620,11 +620,11 @@ void X11SalGraphics::copyArea ( long nDe
     aPosAry.mnSrcWidth  = nSrcWidth;
     aPosAry.mnSrcHeight = nSrcHeight;
     
-    copyBits ( &aPosAry, 0 );
+    copyBits ( aPosAry, 0 );
 }
 
 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap )
+void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
 {
     const SalDisplay*   pSalDisp = GetDisplay();
     Display*			pXDisp = pSalDisp->GetDisplay();
@@ -643,7 +643,7 @@ void X11SalGraphics::drawBitmap( const S
         XChangeGC( pXDisp, aGC, nValues, &aNewVal );
     }
     
-    static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, m_nScreen, nDepth, *pPosAry, aGC );
+    static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, m_nScreen, nDepth, rPosAry, aGC );
     
     if( rSalBitmap.GetBitCount() == 1 )
         XChangeGC( pXDisp, aGC, nValues, &aOldVal );
@@ -652,7 +652,7 @@ void X11SalGraphics::drawBitmap( const S
 
 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry,
+void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry,
                                  const SalBitmap& rSrcBitmap,
                                  const SalBitmap& rMaskBitmap )
 {
@@ -665,15 +665,15 @@ void X11SalGraphics::drawBitmap( const S
         int nMaskFormat = pAlphaBuffer->mnFormat;
         const_cast<SalBitmap&>(rMaskBitmap).ReleaseBuffer( pAlphaBuffer, sal_True );
         if( nMaskFormat == BMP_FORMAT_8BIT_PAL )
-            drawAlphaBitmap( *pPosAry, rSrcBitmap, rMaskBitmap );
+            drawAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
     }
 
-    drawMaskedBitmap( pPosAry, rSrcBitmap, rMaskBitmap );
+    drawMaskedBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
 }
 
 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry,
+void X11SalGraphics::drawMaskedBitmap( const SalTwoRect& rPosAry,
                                        const SalBitmap& rSalBitmap,
                                        const SalBitmap& rTransBitmap )
 {
@@ -687,10 +687,10 @@ void X11SalGraphics::drawMaskedBitmap( c
     const sal_uInt16	nDepth( m_pVDev ? 
                             m_pVDev->GetDepth() :
                             pSalDisp->GetVisual( m_nScreen ).GetDepth() );
-    Pixmap			aFG( XCreatePixmap( pXDisp, aDrawable, pPosAry->mnDestWidth,
-                                        pPosAry->mnDestHeight, nDepth ) );
-    Pixmap			aBG( XCreatePixmap( pXDisp, aDrawable, pPosAry->mnDestWidth,
-                                        pPosAry->mnDestHeight, nDepth ) );
+    Pixmap			aFG( XCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
+                                        rPosAry.mnDestHeight, nDepth ) );
+    Pixmap			aBG( XCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
+                                        rPosAry.mnDestHeight, nDepth ) );
     
     if( aFG && aBG )
     {
@@ -699,7 +699,7 @@ void X11SalGraphics::drawMaskedBitmap( c
         const SalColormap&	rColMap = pSalDisp->GetColormap( m_nScreen );
         const int			nBlack = rColMap.GetBlackPixel(), nWhite = rColMap.GetWhitePixel();
         const int			nValues = GCFunction | GCForeground | GCBackground;
-        SalTwoRect			aTmpRect( *pPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0;
+        SalTwoRect			aTmpRect( rPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0;
         
         // draw paint bitmap in pixmap #1
         aValues.function = GXcopy, aValues.foreground = nWhite, aValues.background = nBlack;
@@ -709,8 +709,8 @@ void X11SalGraphics::drawMaskedBitmap( c
 
         // draw background in pixmap #2
         XCopyArea( pXDisp, aDrawable, aBG, aTmpGC,
-                   pPosAry->mnDestX, pPosAry->mnDestY,
-                   pPosAry->mnDestWidth, pPosAry->mnDestHeight,
+                   rPosAry.mnDestX, rPosAry.mnDestY,
+                   rPosAry.mnDestWidth, rPosAry.mnDestHeight,
                    0, 0 );
 
         DBG_TESTTRANS( aBG );
@@ -738,7 +738,7 @@ void X11SalGraphics::drawMaskedBitmap( c
         XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
         XCopyArea( pXDisp, aFG, aBG, aTmpGC,
                    0, 0,
-                   pPosAry->mnDestWidth, pPosAry->mnDestHeight,
+                   rPosAry.mnDestWidth, rPosAry.mnDestHeight,
 				   0, 0 );
         DBG_TESTTRANS( aBG );
         
@@ -749,8 +749,8 @@ void X11SalGraphics::drawMaskedBitmap( c
         // copy pixmap #2 (result) to background
         XCopyArea( pXDisp, aBG, aDrawable, GetCopyGC(),
                    0, 0,
-                   pPosAry->mnDestWidth, pPosAry->mnDestHeight,
-                   pPosAry->mnDestX, pPosAry->mnDestY );
+                   rPosAry.mnDestWidth, rPosAry.mnDestHeight,
+                   rPosAry.mnDestX, rPosAry.mnDestY );
         
         DBG_TESTTRANS( aBG );
         
@@ -760,7 +760,7 @@ void X11SalGraphics::drawMaskedBitmap( c
         XFlush( pXDisp );
     }
     else
-        drawBitmap( pPosAry, rSalBitmap );
+        drawBitmap( rPosAry, rSalBitmap );
     
     if( aFG )
         XFreePixmap( pXDisp, aFG );
@@ -902,6 +902,19 @@ bool X11SalGraphics::drawAlphaBitmap( co
 }
 
 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+bool X11SalGraphics::drawTransformedBitmap(
+    const basegfx::B2DPoint& rNull,
+    const basegfx::B2DPoint& rX,
+    const basegfx::B2DPoint& rY,
+    const SalBitmap& rSourceBitmap,
+    const SalBitmap* pAlphaBitmap)
+{
+    // here direct support for transformed bitmaps can be impemented
+    (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
+    return false;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 bool X11SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, 
                                     long nHeight, sal_uInt8 nTransparency )
 {
@@ -935,7 +948,7 @@ bool X11SalGraphics::drawAlphaRect( long
 }
 
 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawBitmap( const SalTwoRect*,
+void X11SalGraphics::drawBitmap( const SalTwoRect&,
                                  const SalBitmap&,
                                  SalColor )
 {
@@ -943,7 +956,7 @@ void X11SalGraphics::drawBitmap( const S
 }
 
 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawMask( const SalTwoRect* pPosAry,
+void X11SalGraphics::drawMask( const SalTwoRect& rPosAry,
                                const SalBitmap &rSalBitmap,
                                SalColor nMaskColor )
 {
@@ -951,12 +964,12 @@ void X11SalGraphics::drawMask( const Sal
     Display*	        pXDisp = pSalDisp->GetDisplay();
     Drawable            aDrawable( GetDrawable() );
     Pixmap              aStipple( XCreatePixmap( pXDisp, aDrawable,
-                                                 pPosAry->mnDestWidth,
-                                                 pPosAry->mnDestHeight, 1 ) );
+                                                 rPosAry.mnDestWidth,
+                                                 rPosAry.mnDestHeight, 1 ) );
     
     if( aStipple )
     {
-        SalTwoRect	aTwoRect( *pPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
+        SalTwoRect	aTwoRect( rPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
         GC			aTmpGC;
         XGCValues	aValues;
         
@@ -970,19 +983,19 @@ void X11SalGraphics::drawMask( const Sal
         
         // Set stipple and draw rectangle
         GC	aStippleGC( GetStippleGC() );
-        int	nX = pPosAry->mnDestX, nY = pPosAry->mnDestY;
+        int	nX = rPosAry.mnDestX, nY = rPosAry.mnDestY;
         
         XSetStipple( pXDisp, aStippleGC, aStipple );
         XSetTSOrigin( pXDisp, aStippleGC, nX, nY );
         XSetForeground( pXDisp, aStippleGC, GetPixel( nMaskColor ) );
         XFillRectangle( pXDisp, aDrawable, aStippleGC,
                         nX, nY,
-                        pPosAry->mnDestWidth, pPosAry->mnDestHeight );
+                        rPosAry.mnDestWidth, rPosAry.mnDestHeight );
         XFreePixmap( pXDisp, aStipple );
         XFlush( pXDisp );
     }
     else
-        drawBitmap( pPosAry, rSalBitmap );
+        drawBitmap( rPosAry, rSalBitmap );
 }
 
 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Modified: openoffice/trunk/main/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx (original)
+++ openoffice/trunk/main/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx Wed Jan 23 14:27:50 2013
@@ -484,7 +484,7 @@ bool GtkSalGraphics::setClipRegion( cons
     return bRet;
 }
 
-void GtkSalGraphics::copyBits( const SalTwoRect* pPosAry,
+void GtkSalGraphics::copyBits( const SalTwoRect& rPosAry,
                                SalGraphics* pSrcGraphics )
 {
     GtkSalFrame* pFrame = GetGtkFrame();
@@ -502,7 +502,7 @@ void GtkSalGraphics::copyBits( const Sal
                                             None );
         }
     }
-    X11SalGraphics::copyBits( pPosAry, pSrcGraphics );
+    X11SalGraphics::copyBits( rPosAry, pSrcGraphics );
     if( pFrame && pFrame->getBackgroundPixmap() != None )
         XSetWindowBackgroundPixmap( pFrame->getDisplay()->GetDisplay(),
                                     aWin,

Modified: openoffice/trunk/main/vcl/unx/headless/svpgdi.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/unx/headless/svpgdi.cxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/unx/headless/svpgdi.cxx (original)
+++ openoffice/trunk/main/vcl/unx/headless/svpgdi.cxx Wed Jan 23 14:27:50 2013
@@ -75,6 +75,18 @@ bool SvpSalGraphics::drawAlphaBitmap( co
 	return false;
 }
 
+bool SvpSalGraphics::drawTransformedBitmap(
+    const basegfx::B2DPoint& rNull,
+    const basegfx::B2DPoint& rX,
+    const basegfx::B2DPoint& rY,
+    const SalBitmap& rSourceBitmap,
+    const SalBitmap* pAlphaBitmap)
+{
+    // here direct support for transformed bitmaps can be impemented
+    (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
+    return false;
+}
+
 bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8 /*nTransparency*/ )
 {
 	// TODO(P3) implement alpha blending
@@ -148,71 +160,71 @@ void SvpSalGraphics::ResetClipRegion()
     m_aClipMap.reset();
 }
 
-bool SvpSalGraphics::setClipRegion( const Region& i_rClip )
-{
-    if( i_rClip.IsEmpty() )
-    {
-        m_aClipMap.reset();
-        return true;
-    }
-
-    RectangleVector aRectangles;
-    i_rClip.GetRegionRectangles(aRectangles);
-
-    if(1 == aRectangles.size())
-    {
-        m_aClipMap.reset();
-        const Rectangle& aBoundRect = aRectangles[0];
-        m_aDevice = basebmp::subsetBitmapDevice( 
-            m_aOrigDevice,
-            basegfx::B2IRange(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right(),aBoundRect.Bottom()) );
-        return true;
-    }
-
-    m_aDevice = m_aOrigDevice;
-    B2IVector aSize = m_aDevice->getSize();
-    m_aClipMap = createBitmapDevice( aSize, false, Format::ONE_BIT_MSB_GREY );
-    m_aClipMap->clear( basebmp::Color(0xFFFFFFFF) );
-
-    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
-    {
-        const long nW(aRectIter->GetWidth());
-
-        if(nW)
-        {
-            const long nH(aRectIter->GetHeight());
-
-            if(nH)
-            {
-                B2DPolyPolygon aFull;
-                
-                aFull.append(
-                    tools::createPolygonFromRect(
-                        B2DRectangle(
-                            aRectIter->Left(), 
-                            aRectIter->Top(), 
-                            aRectIter->Left() + nW, 
-                            aRectIter->Top() + nH))); 
-                m_aClipMap->fillPolyPolygon(aFull, basebmp::Color(0), DrawMode_PAINT);
-            }
-        }
-    }
-
-    //ImplRegionInfo aInfo;
-    //long nX, nY, nW, nH;
-    //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
-    //while( bRegionRect )
-    //{
-    //    if ( nW && nH )
-    //    {
-    //        B2DPolyPolygon aFull;
-    //        aFull.append( tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nW, nY+nH ) ) ); 
-    //        m_aClipMap->fillPolyPolygon( aFull, basebmp::Color(0), DrawMode_PAINT );
-    //    }
-    //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
-    //}
-    return true;
-}
+bool SvpSalGraphics::setClipRegion( const Region& i_rClip )
+{
+    if( i_rClip.IsEmpty() )
+    {
+        m_aClipMap.reset();
+        return true;
+    }
+
+    RectangleVector aRectangles;
+    i_rClip.GetRegionRectangles(aRectangles);
+
+    if(1 == aRectangles.size())
+    {
+        m_aClipMap.reset();
+        const Rectangle& aBoundRect = aRectangles[0];
+        m_aDevice = basebmp::subsetBitmapDevice( 
+            m_aOrigDevice,
+            basegfx::B2IRange(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right(),aBoundRect.Bottom()) );
+        return true;
+    }
+
+    m_aDevice = m_aOrigDevice;
+    B2IVector aSize = m_aDevice->getSize();
+    m_aClipMap = createBitmapDevice( aSize, false, Format::ONE_BIT_MSB_GREY );
+    m_aClipMap->clear( basebmp::Color(0xFFFFFFFF) );
+
+    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
+    {
+        const long nW(aRectIter->GetWidth());
+
+        if(nW)
+        {
+            const long nH(aRectIter->GetHeight());
+
+            if(nH)
+            {
+                B2DPolyPolygon aFull;
+                
+                aFull.append(
+                    tools::createPolygonFromRect(
+                        B2DRectangle(
+                            aRectIter->Left(), 
+                            aRectIter->Top(), 
+                            aRectIter->Left() + nW, 
+                            aRectIter->Top() + nH))); 
+                m_aClipMap->fillPolyPolygon(aFull, basebmp::Color(0), DrawMode_PAINT);
+            }
+        }
+    }
+
+    //ImplRegionInfo aInfo;
+    //long nX, nY, nW, nH;
+    //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
+    //while( bRegionRect )
+    //{
+    //    if ( nW && nH )
+    //    {
+    //        B2DPolyPolygon aFull;
+    //        aFull.append( tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nW, nY+nH ) ) ); 
+    //        m_aClipMap->fillPolyPolygon( aFull, basebmp::Color(0), DrawMode_PAINT );
+    //    }
+    //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
+    //}
+    return true;
+}
 
 void SvpSalGraphics::SetLineColor()
 {
@@ -455,73 +467,72 @@ void SvpSalGraphics::copyArea( long nDes
     dbgOut( m_aDevice );
 }
 
-void SvpSalGraphics::copyBits( const SalTwoRect* pPosAry,
+void SvpSalGraphics::copyBits( const SalTwoRect& rPosAry,
                                SalGraphics*      pSrcGraphics )
 {
     SvpSalGraphics* pSrc = pSrcGraphics ? 
         static_cast<SvpSalGraphics*>(pSrcGraphics) : this;
-    B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
-                       pPosAry->mnSrcX+pPosAry->mnSrcWidth,
-                       pPosAry->mnSrcY+pPosAry->mnSrcHeight );
-    B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY,
-                        pPosAry->mnDestX+pPosAry->mnDestWidth,
-                        pPosAry->mnDestY+pPosAry->mnDestHeight );
+    B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
+                       rPosAry.mnSrcX+rPosAry.mnSrcWidth,
+                       rPosAry.mnSrcY+rPosAry.mnSrcHeight );
+    B2IRange aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
+                        rPosAry.mnDestX+rPosAry.mnDestWidth,
+                        rPosAry.mnDestY+rPosAry.mnDestHeight );
     m_aDevice->drawBitmap( pSrc->m_aOrigDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap );    
     dbgOut( m_aDevice );
 }
 
-void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry,
-                                        const SalBitmap& rSalBitmap )
+void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
 {
     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
-    B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
-                       pPosAry->mnSrcX+pPosAry->mnSrcWidth,
-                       pPosAry->mnSrcY+pPosAry->mnSrcHeight );
-    B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY,
-                        pPosAry->mnDestX+pPosAry->mnDestWidth,
-                        pPosAry->mnDestY+pPosAry->mnDestHeight );
+    B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
+                       rPosAry.mnSrcX+rPosAry.mnSrcWidth,
+                       rPosAry.mnSrcY+rPosAry.mnSrcHeight );
+    B2IRange aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
+                        rPosAry.mnDestX+rPosAry.mnDestWidth,
+                        rPosAry.mnDestY+rPosAry.mnDestHeight );
     m_aDevice->drawBitmap( rSrc.getBitmap(), aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap );    
     dbgOut( m_aDevice );
 }
 
-void SvpSalGraphics::drawBitmap( const SalTwoRect*,
+void SvpSalGraphics::drawBitmap( const SalTwoRect&,
                                  const SalBitmap&,
                                  SalColor )
 {
     // SNI, as in X11 plugin
 }
 
-void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry,
+void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry,
                                  const SalBitmap& rSalBitmap,
                                  const SalBitmap& rTransparentBitmap )
 {
     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
     const SvpSalBitmap& rSrcTrans = static_cast<const SvpSalBitmap&>(rTransparentBitmap);
-    B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
-                       pPosAry->mnSrcX+pPosAry->mnSrcWidth,
-                       pPosAry->mnSrcY+pPosAry->mnSrcHeight );
-    B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY,
-                        pPosAry->mnDestX+pPosAry->mnDestWidth,
-                        pPosAry->mnDestY+pPosAry->mnDestHeight );
+    B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
+                       rPosAry.mnSrcX+rPosAry.mnSrcWidth,
+                       rPosAry.mnSrcY+rPosAry.mnSrcHeight );
+    B2IRange aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
+                        rPosAry.mnDestX+rPosAry.mnDestWidth,
+                        rPosAry.mnDestY+rPosAry.mnDestHeight );
     m_aDevice->drawMaskedBitmap( rSrc.getBitmap(), rSrcTrans.getBitmap(), aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap );
     dbgOut( m_aDevice );
 }
 
-void SvpSalGraphics::drawMask( const SalTwoRect* pPosAry,
+void SvpSalGraphics::drawMask( const SalTwoRect& rPosAry,
                                const SalBitmap& rSalBitmap,
                                SalColor nMaskColor )
 {
     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
-    B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
-                       pPosAry->mnSrcX+pPosAry->mnSrcWidth,
-                       pPosAry->mnSrcY+pPosAry->mnSrcHeight );
-    B2IPoint aDestPoint( pPosAry->mnDestX, pPosAry->mnDestY );
+    B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
+                       rPosAry.mnSrcX+rPosAry.mnSrcWidth,
+                       rPosAry.mnSrcY+rPosAry.mnSrcHeight );
+    B2IPoint aDestPoint( rPosAry.mnDestX, rPosAry.mnDestY );
 
     // BitmapDevice::drawMaskedColor works with 0==transparent,
     // 255==opaque. drawMask() semantic is the other way
     // around. Therefore, invert mask.
     BitmapDeviceSharedPtr aCopy =
-        cloneBitmapDevice( B2IVector( pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ),
+        cloneBitmapDevice( B2IVector( rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ),
                            rSrc.getBitmap() );
     basebmp::Color aBgColor( COL_WHITE );
     aCopy->clear(aBgColor);
@@ -529,7 +540,7 @@ void SvpSalGraphics::drawMask( const Sal
     aCopy->drawMaskedColor( aFgColor, rSrc.getBitmap(), aSrcRect, B2IPoint() );
 
     basebmp::Color aColor( nMaskColor );
-    B2IRange aSrcRect2( 0, 0, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight );
+    B2IRange aSrcRect2( 0, 0, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight );
     m_aDevice->drawMaskedColor( aColor, aCopy, aSrcRect, aDestPoint, m_aClipMap );
     dbgOut( m_aDevice );
 }

Modified: openoffice/trunk/main/vcl/unx/headless/svpgdi.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/unx/headless/svpgdi.hxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/unx/headless/svpgdi.hxx (original)
+++ openoffice/trunk/main/vcl/unx/headless/svpgdi.hxx Wed Jan 23 14:27:50 2013
@@ -50,6 +50,12 @@ class SvpSalGraphics : public SalGraphic
 
 protected:
     virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap );
+    virtual bool drawTransformedBitmap(
+        const basegfx::B2DPoint& rNull,
+        const basegfx::B2DPoint& rX,
+        const basegfx::B2DPoint& rY,
+        const SalBitmap& rSourceBitmap,
+        const SalBitmap* pAlphaBitmap);
     virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency );
 
 public:
@@ -144,17 +150,17 @@ public:
                                       long nSrcWidth,
                                       long nSrcHeight,
                                       sal_uInt16 nFlags );
-    virtual void			copyBits( const SalTwoRect* pPosAry,
+    virtual void			copyBits( const SalTwoRect& rPosAry,
                                       SalGraphics* pSrcGraphics );
-    virtual void			drawBitmap( const SalTwoRect* pPosAry,
+    virtual void			drawBitmap( const SalTwoRect& rPosAry,
                                         const SalBitmap& rSalBitmap );
-    virtual void			drawBitmap( const SalTwoRect* pPosAry,
+    virtual void			drawBitmap( const SalTwoRect& rPosAry,
                                         const SalBitmap& rSalBitmap,
                                         SalColor nTransparentColor );
-    virtual void			drawBitmap( const SalTwoRect* pPosAry,
+    virtual void			drawBitmap( const SalTwoRect& rPosAry,
                                         const SalBitmap& rSalBitmap,
                                         const SalBitmap& rTransparentBitmap );
-    virtual void			drawMask( const SalTwoRect* pPosAry,
+    virtual void			drawMask( const SalTwoRect& rPosAry,
                                       const SalBitmap& rSalBitmap,
                                       SalColor nMaskColor );
     virtual SalBitmap*		getBitmap( long nX, long nY, long nWidth, long nHeight );

Modified: openoffice/trunk/main/vcl/unx/headless/svppspgraphics.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/unx/headless/svppspgraphics.cxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/unx/headless/svppspgraphics.cxx (original)
+++ openoffice/trunk/main/vcl/unx/headless/svppspgraphics.cxx Wed Jan 23 14:27:50 2013
@@ -175,6 +175,18 @@ bool PspGraphics::drawAlphaBitmap( const
 	return false;
 }
 
+bool PspGraphics::drawTransformedBitmap(
+    const basegfx::B2DPoint& rNull,
+    const basegfx::B2DPoint& rX,
+    const basegfx::B2DPoint& rY,
+    const SalBitmap& rSourceBitmap,
+    const SalBitmap* pAlphaBitmap)
+{
+    // here direct support for transformed bitmaps can be impemented
+    (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
+    return false;
+}
+
 bool PspGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8 /*nTransparency*/ )
 {
 	return false;
@@ -391,7 +403,7 @@ sal_Bool PspGraphics::drawEPS( long nX, 
     return m_pPrinterGfx->DrawEPS( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ), pPtr, nSize );
 }
 
-void PspGraphics::copyBits( const SalTwoRect* /*pPosAry*/,
+void PspGraphics::copyBits( const SalTwoRect& /*rPosAry*/,
                             SalGraphics* /*pSSrcGraphics*/ )
 {
     DBG_ERROR( "Error: PrinterGfx::CopyBits() not implemented" );
@@ -405,12 +417,12 @@ void PspGraphics::copyArea ( long /*nDes
     DBG_ERROR( "Error: PrinterGfx::CopyArea() not implemented" );
 }
 
-void PspGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap )
+void PspGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
 {
-    Rectangle aSrc (Point(pPosAry->mnSrcX, pPosAry->mnSrcY),
-                    Size(pPosAry->mnSrcWidth, pPosAry->mnSrcHeight));
-    Rectangle aDst (Point(pPosAry->mnDestX, pPosAry->mnDestY),
-                    Size(pPosAry->mnDestWidth, pPosAry->mnDestHeight));
+    Rectangle aSrc (Point(rPosAry.mnSrcX, rPosAry.mnSrcY),
+                    Size(rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
+    Rectangle aDst (Point(rPosAry.mnDestX, rPosAry.mnDestY),
+                    Size(rPosAry.mnDestWidth, rPosAry.mnDestHeight));
 
     const SvpSalBitmap* pBmp = dynamic_cast<const SvpSalBitmap*>(&rSalBitmap);
     if( pBmp )
@@ -420,21 +432,21 @@ void PspGraphics::drawBitmap( const SalT
     }
 }
 
-void PspGraphics::drawBitmap( const SalTwoRect* /*pPosAry*/,
+void PspGraphics::drawBitmap( const SalTwoRect& /*pPosAry*/,
                               const SalBitmap& /*rSalBitmap*/,
                               const SalBitmap& /*rTransBitmap*/ )
 {
     DBG_ERROR("Error: no PrinterGfx::DrawBitmap() for transparent bitmap");
 }
 
-void PspGraphics::drawBitmap( const SalTwoRect* /*pPosAry*/,
+void PspGraphics::drawBitmap( const SalTwoRect& /*pPosAry*/,
                               const SalBitmap& /*rSalBitmap*/,
                               SalColor /*nTransparentColor*/ )
 {
     DBG_ERROR("Error: no PrinterGfx::DrawBitmap() for transparent color");
 }
 
-void PspGraphics::drawMask( const SalTwoRect* /*pPosAry*/,
+void PspGraphics::drawMask( const SalTwoRect& /*rPosAry*/,
                             const SalBitmap& /*rSalBitmap*/,
                             SalColor /*nMaskColor*/ )
 {

Modified: openoffice/trunk/main/vcl/unx/headless/svppspgraphics.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/unx/headless/svppspgraphics.hxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/unx/headless/svppspgraphics.hxx (original)
+++ openoffice/trunk/main/vcl/unx/headless/svppspgraphics.hxx Wed Jan 23 14:27:50 2013
@@ -51,6 +51,12 @@ class PspGraphics : public SalGraphics
 
 protected:
     virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap );
+    virtual bool drawTransformedBitmap(
+        const basegfx::B2DPoint& rNull,
+        const basegfx::B2DPoint& rX,
+        const basegfx::B2DPoint& rY,
+        const SalBitmap& rSourceBitmap,
+        const SalBitmap* pAlphaBitmap);
     virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency );
 
 public:
@@ -163,17 +169,17 @@ public:
                                       long nSrcWidth,
                                       long nSrcHeight,
                                       sal_uInt16 nFlags );
-    virtual void			copyBits( const SalTwoRect* pPosAry,
+    virtual void			copyBits( const SalTwoRect& rPosAry,
                                       SalGraphics* pSrcGraphics );
-    virtual void			drawBitmap( const SalTwoRect* pPosAry,
+    virtual void			drawBitmap( const SalTwoRect& rPosAry,
                                         const SalBitmap& rSalBitmap );
-    virtual void			drawBitmap( const SalTwoRect* pPosAry,
+    virtual void			drawBitmap( const SalTwoRect& rPosAry,
                                         const SalBitmap& rSalBitmap,
                                         SalColor nTransparentColor );
-    virtual void			drawBitmap( const SalTwoRect* pPosAry,
+    virtual void			drawBitmap( const SalTwoRect& rPosAry,
                                         const SalBitmap& rSalBitmap,
                                         const SalBitmap& rTransparentBitmap );
-    virtual void			drawMask( const SalTwoRect* pPosAry,
+    virtual void			drawMask( const SalTwoRect& rPosAry,
                                       const SalBitmap& rSalBitmap,
                                       SalColor nMaskColor );
     virtual SalBitmap*		getBitmap( long nX, long nY, long nWidth, long nHeight );

Modified: openoffice/trunk/main/vcl/win/source/gdi/salbmp.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/win/source/gdi/salbmp.cxx?rev=1437407&r1=1437406&r2=1437407&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/win/source/gdi/salbmp.cxx (original)
+++ openoffice/trunk/main/vcl/win/source/gdi/salbmp.cxx Wed Jan 23 14:27:50 2013
@@ -19,26 +19,32 @@
  * 
  *************************************************************/
 
-
-
 // MARKER(update_precomp.py): autogen include statement, do not remove
 #include "precompiled_vcl.hxx"
 
 #include <tools/svwin.h>
-
 #include <vcl/bitmap.hxx> // for BitmapSystemData
 #include <vcl/salbtype.hxx>
-
 #include <win/wincomp.hxx>
 #include <win/salgdi.h>
 #include <win/saldata.hxx>
 #include <win/salbmp.h>
-
 #include <string.h>
+#include <vcl/timer.hxx>
+#include <comphelper/broadcasthelper.hxx>
+#include <map>
+
+#ifndef min
+#define min(a,b)	(((a) < (b)) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a,b)	(((a) > (b)) ? (a) : (b))
+#endif
 
-// -----------
+#include <GdiPlus.h>
+
+// ------------------------------------------------------------------
 // - Inlines -
-// -----------
 
 inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex )
 {
@@ -48,14 +54,139 @@ inline void ImplSetPixel4( const HPBYTE 
 				 ( rByte &= 0x0f, rByte |= ( cIndex << 4 ) );
 }
 
-// ----------------
+// ------------------------------------------------------------------
+// Helper class to manage Gdiplus::Bitmap instances inside of
+// WinSalBitmap
+
+struct Comparator
+{
+    bool operator()(WinSalBitmap* pA, WinSalBitmap* pB) const
+    {
+        return pA < pB;
+    }
+};
+
+typedef ::std::map< WinSalBitmap*, sal_uInt32, Comparator > EntryMap;
+static const sal_uInt32 nDefaultCycles(60);
+
+class GdiPlusBuffer : protected comphelper::OBaseMutex, public Timer
+{
+private:
+    EntryMap        maEntries;
+
+public:
+    GdiPlusBuffer() 
+    :   Timer(),
+        maEntries()
+    {
+        SetTimeout(1000);
+        Stop();
+    }
+
+    ~GdiPlusBuffer()
+    {
+        Stop();
+    }
+
+    void addEntry(WinSalBitmap& rEntry)
+    {
+        ::osl::MutexGuard aGuard(m_aMutex);
+        EntryMap::iterator aFound = maEntries.find(&rEntry);
+
+        if(aFound == maEntries.end())
+        {
+            if(maEntries.empty())
+            {
+                Start();
+            }
+
+            maEntries[&rEntry] = nDefaultCycles;
+        }
+    }
+
+    void remEntry(WinSalBitmap& rEntry)
+    {
+        ::osl::MutexGuard aGuard(m_aMutex);
+        EntryMap::iterator aFound = maEntries.find(&rEntry);
+
+        if(aFound != maEntries.end())
+        {
+            maEntries.erase(aFound);
+
+            if(maEntries.empty())
+            {
+                Stop();
+            }
+        }
+    }
+
+    void touchEntry(WinSalBitmap& rEntry)
+    {
+        ::osl::MutexGuard aGuard(m_aMutex);
+        EntryMap::iterator aFound = maEntries.find(&rEntry);
+
+        if(aFound != maEntries.end())
+        {
+            aFound->second = nDefaultCycles;
+        }
+    }
+
+    // from parent Timer
+    virtual void Timeout()
+    {
+        ::osl::MutexGuard aGuard(m_aMutex);
+        EntryMap::iterator aIter(maEntries.begin());
+
+        while(aIter != maEntries.end())
+        {
+            if(aIter->second)
+            {
+                aIter->second--;
+                aIter++;
+            }
+            else
+            {
+                EntryMap::iterator aDelete(aIter);
+                WinSalBitmap* pSource = aDelete->first;
+                aIter++;
+                maEntries.erase(aDelete);
+
+                if(maEntries.empty())
+                {
+                    Stop();
+                }
+
+                // delete at WinSalBitmap after entry is removed; this
+                // way it would not hurt to call remEntry from there, too
+                if(pSource->maGdiPlusBitmap.get())
+                {
+                    pSource->maGdiPlusBitmap.reset();
+                }
+            }
+        }
+
+        if(!maEntries.empty())
+        {
+            Start();
+        }
+    }
+};
+
+// ------------------------------------------------------------------
+// Global instance of GdiPlusBuffer which manages Gdiplus::Bitmap
+// instances
+
+static GdiPlusBuffer aGdiPlusBuffer;
+
+// ------------------------------------------------------------------
 // - WinSalBitmap -
-// ----------------
 
-WinSalBitmap::WinSalBitmap() :
-		mhDIB		( 0 ),
-		mhDDB		( 0 ),
-		mnBitCount	( 0 )
+WinSalBitmap::WinSalBitmap() 
+:   maSize(),
+    mhDIB(0),
+    mhDDB(0),
+    maGdiPlusBitmap(),
+    mnBitCount(0)
 {
 }
 
@@ -68,6 +199,292 @@ WinSalBitmap::~WinSalBitmap()
 
 // ------------------------------------------------------------------
 
+void WinSalBitmap::Destroy()
+{
+    if(maGdiPlusBitmap.get())
+    {
+        aGdiPlusBuffer.remEntry(*this);
+    }
+
+    if( mhDIB )
+		GlobalFree( mhDIB );
+	else if( mhDDB )
+		DeleteObject( mhDDB );
+
+	maSize = Size();
+	mnBitCount = 0;
+}
+
+// ------------------------------------------------------------------
+
+GdiPlusBmpPtr WinSalBitmap::ImplGetGdiPlusBitmap(const WinSalBitmap* pAlphaSource) const 
+{ 
+    if(maGdiPlusBitmap.get())
+    {
+        aGdiPlusBuffer.touchEntry(const_cast< WinSalBitmap& >(*this));
+    }
+    else
+    {
+        if(maSize.Width() > 0 && maSize.Height() > 0)
+        {
+            WinSalBitmap* pThat = const_cast< WinSalBitmap* >(this);
+
+            if(pAlphaSource)
+            {
+                pThat->maGdiPlusBitmap.reset(pThat->ImplCreateGdiPlusBitmap(*pAlphaSource));
+            }
+            else
+            {
+                pThat->maGdiPlusBitmap.reset(pThat->ImplCreateGdiPlusBitmap());
+            }
+
+            if(maGdiPlusBitmap.get())
+            {
+                aGdiPlusBuffer.addEntry(*pThat);
+            }
+        }
+    }
+
+    return maGdiPlusBitmap; 
+}
+
+// ------------------------------------------------------------------
+
+Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap()
+{
+    Gdiplus::Bitmap* pRetval(0);
+    WinSalBitmap* pSalRGB = const_cast< WinSalBitmap* >(this);
+    WinSalBitmap* pExtraWinSalRGB = 0;
+
+    if(!pSalRGB->ImplGethDIB())
+    {
+        // we need DIB for success with AcquireBuffer, create a replacement WinSalBitmap
+        pExtraWinSalRGB = new WinSalBitmap();
+        pExtraWinSalRGB->Create(*pSalRGB, pSalRGB->GetBitCount());
+        pSalRGB = pExtraWinSalRGB;
+    }
+
+    BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(true);
+    BitmapBuffer* pExtraRGB = 0;
+
+    if(pRGB && BMP_FORMAT_24BIT_TC_BGR != (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN))
+    {
+        // convert source bitmap to BMP_FORMAT_24BIT_TC_BGR format if not yet in that format
+        SalTwoRect aSalTwoRect;
+
+        aSalTwoRect.mnSrcX = aSalTwoRect.mnSrcY = aSalTwoRect.mnDestX = aSalTwoRect.mnDestY = 0;
+        aSalTwoRect.mnSrcWidth = aSalTwoRect.mnDestWidth = pRGB->mnWidth;
+        aSalTwoRect.mnSrcHeight = aSalTwoRect.mnDestHeight = pRGB->mnHeight;
+
+        pExtraRGB = StretchAndConvert( 
+            *pRGB,
+            aSalTwoRect,
+            BMP_FORMAT_24BIT_TC_BGR,
+            0);
+
+        pSalRGB->ReleaseBuffer(pRGB, true);
+        pRGB = pExtraRGB;
+    }
+
+    if(pRGB 
+        && pRGB->mnWidth > 0
+        && pRGB->mnHeight > 0
+        && BMP_FORMAT_24BIT_TC_BGR == (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN))
+    {
+        const sal_uInt32 nW(pRGB->mnWidth);
+        const sal_uInt32 nH(pRGB->mnHeight);
+
+        pRetval = new Gdiplus::Bitmap(nW, nH, PixelFormat24bppRGB);
+
+        if(pRetval)
+        {
+            sal_uInt8* pSrcRGB(pRGB->mpBits);
+            const sal_uInt32 nExtraRGB(pRGB->mnScanlineSize - (nW * 3));
+            const bool bTopDown(pRGB->mnFormat & BMP_FORMAT_TOP_DOWN);
+
+            for(sal_uInt32 y(0); y < nH; y++)
+            {
+                const sal_uInt32 nYInsert(bTopDown ? y : nH - y - 1);
+
+                for(sal_uInt32 x(0); x < nW; x++)
+                {
+                    const sal_uInt8 nB(*pSrcRGB++);
+                    const sal_uInt8 nG(*pSrcRGB++);
+                    const sal_uInt8 nR(*pSrcRGB++);
+
+                    pRetval->SetPixel(x, nYInsert, Gdiplus::Color(nR, nG, nB));
+                }
+
+                pSrcRGB += nExtraRGB;
+            }
+        }
+    }
+
+    if(pExtraRGB)
+    {
+        delete pExtraRGB;
+    }
+    else
+    {
+        pSalRGB->ReleaseBuffer(pRGB, true);
+    }
+
+    if(pExtraWinSalRGB)
+    {
+        delete pExtraWinSalRGB;
+    }
+
+    return pRetval;
+}
+
+// ------------------------------------------------------------------
+
+Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlphaSource)
+{
+    Gdiplus::Bitmap* pRetval(0);
+    WinSalBitmap* pSalRGB = const_cast< WinSalBitmap* >(this);
+    WinSalBitmap* pExtraWinSalRGB = 0;
+
+    if(!pSalRGB->ImplGethDIB())
+    {
+        // we need DIB for success with AcquireBuffer, create a replacement WinSalBitmap
+        pExtraWinSalRGB = new WinSalBitmap();
+        pExtraWinSalRGB->Create(*pSalRGB, pSalRGB->GetBitCount());
+        pSalRGB = pExtraWinSalRGB;
+    }
+
+    BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(true);
+    BitmapBuffer* pExtraRGB = 0;
+
+    if(pRGB && BMP_FORMAT_24BIT_TC_BGR != (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN))
+    {
+        // convert source bitmap to BMP_FORMAT_24BIT_TC_BGR format if not yet in that format
+        SalTwoRect aSalTwoRect;
+
+        aSalTwoRect.mnSrcX = aSalTwoRect.mnSrcY = aSalTwoRect.mnDestX = aSalTwoRect.mnDestY = 0;
+        aSalTwoRect.mnSrcWidth = aSalTwoRect.mnDestWidth = pRGB->mnWidth;
+        aSalTwoRect.mnSrcHeight = aSalTwoRect.mnDestHeight = pRGB->mnHeight;
+
+        pExtraRGB = StretchAndConvert( 
+            *pRGB,
+            aSalTwoRect,
+            BMP_FORMAT_24BIT_TC_BGR,
+            0);
+
+        pSalRGB->ReleaseBuffer(pRGB, true);
+        pRGB = pExtraRGB;
+    }
+
+    WinSalBitmap* pSalA = const_cast< WinSalBitmap* >(&rAlphaSource);
+    WinSalBitmap* pExtraWinSalA = 0;
+
+    if(!pSalA->ImplGethDIB())
+    {
+        // we need DIB for success with AcquireBuffer, create a replacement WinSalBitmap
+        pExtraWinSalA = new WinSalBitmap();
+        pExtraWinSalA->Create(*pSalA, pSalA->GetBitCount());
+        pSalA = pExtraWinSalA;
+    }
+
+    BitmapBuffer* pA = pSalA->AcquireBuffer(true);
+    BitmapBuffer* pExtraA = 0;
+
+    if(pA && BMP_FORMAT_8BIT_PAL != (pA->mnFormat & ~BMP_FORMAT_TOP_DOWN))
+    {
+        // convert alpha bitmap to BMP_FORMAT_8BIT_PAL format if not yet in that format
+        SalTwoRect aSalTwoRect;
+
+        aSalTwoRect.mnSrcX = aSalTwoRect.mnSrcY = aSalTwoRect.mnDestX = aSalTwoRect.mnDestY = 0;
+        aSalTwoRect.mnSrcWidth = aSalTwoRect.mnDestWidth = pA->mnWidth;
+        aSalTwoRect.mnSrcHeight = aSalTwoRect.mnDestHeight = pA->mnHeight;
+        const BitmapPalette& rTargetPalette = Bitmap::GetGreyPalette(256);
+
+        pExtraA = StretchAndConvert( 
+            *pA,
+            aSalTwoRect,
+            BMP_FORMAT_8BIT_PAL,
+            &rTargetPalette);
+
+        pSalA->ReleaseBuffer(pA, true);
+        pA = pExtraA;
+    }
+
+    if(pRGB 
+        && pA 
+        && pRGB->mnWidth > 0
+        && pRGB->mnHeight > 0
+        && pRGB->mnWidth == pA->mnWidth 
+        && pRGB->mnHeight == pA->mnHeight 
+        && BMP_FORMAT_24BIT_TC_BGR == (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN)
+        && BMP_FORMAT_8BIT_PAL == (pA->mnFormat & ~BMP_FORMAT_TOP_DOWN))
+    {
+        // we have alpha and bitmap in known formats, create GdiPlus Bitmap as 32bit ARGB
+        const sal_uInt32 nW(pRGB->mnWidth);
+        const sal_uInt32 nH(pRGB->mnHeight);
+
+        pRetval = new Gdiplus::Bitmap(nW, nH, PixelFormat32bppARGB);
+
+        if(pRetval)
+        {
+            sal_uInt8* pSrcRGB(pRGB->mpBits);
+            sal_uInt8* pSrcA(pA->mpBits);
+            const sal_uInt32 nExtraRGB(pRGB->mnScanlineSize - (nW * 3));
+            const sal_uInt32 nExtraA(pA->mnScanlineSize - nW);
+            const bool bTopDown(pRGB->mnFormat & BMP_FORMAT_TOP_DOWN);
+
+            for(sal_uInt32 y(0); y < nH; y++)
+            {
+                const sal_uInt32 nYInsert(bTopDown ? y : nH - y - 1);
+
+                for(sal_uInt32 x(0); x < nW; x++)
+                {
+                    const sal_uInt8 nB(*pSrcRGB++);
+                    const sal_uInt8 nG(*pSrcRGB++);
+                    const sal_uInt8 nR(*pSrcRGB++);
+                    const sal_uInt8 nA(0xff - *pSrcA++);
+
+                    pRetval->SetPixel(x, nYInsert, Gdiplus::Color(nA, nR, nG, nB));
+                }
+
+                pSrcRGB += nExtraRGB;
+                pSrcA += nExtraA;
+            }
+        }
+    }
+
+    if(pExtraA)
+    {
+        delete pExtraA;
+    }
+    else
+    {
+        pSalA->ReleaseBuffer(pA, true);
+    }
+
+    if(pExtraWinSalA)
+    {
+        delete pExtraWinSalA;
+    }
+
+    if(pExtraRGB)
+    {
+        delete pExtraRGB;
+    }
+    else
+    {
+        pSalRGB->ReleaseBuffer(pRGB, true);
+    }
+
+    if(pExtraWinSalRGB)
+    {
+        delete pExtraWinSalRGB;
+    }
+
+    return pRetval;
+}
+
+// ------------------------------------------------------------------
+
 bool WinSalBitmap::Create( HANDLE hBitmap, bool bDIB, bool bCopyHandle )
 {
 	bool bRet = TRUE;
@@ -177,7 +594,7 @@ bool WinSalBitmap::Create( const SalBitm
 	{
 		PBITMAPINFO 		pBI = (PBITMAPINFO) GlobalLock( rSalBmp.mhDIB );
 		PBITMAPINFOHEADER	pBIH = (PBITMAPINFOHEADER) pBI;
-		HDC 				hDC  = pGraphics->mhDC;
+		HDC 				hDC  = pGraphics->getHDC();
 		HBITMAP 			hNewDDB;
 		BITMAP				aDDBInfo;
 		PBYTE				pBits = (PBYTE) pBI + *(DWORD*) pBI +
@@ -264,19 +681,6 @@ bool WinSalBitmap::Create( const SalBitm
 
 // ------------------------------------------------------------------
 
-void WinSalBitmap::Destroy()
-{
-	if( mhDIB )
-		GlobalFree( mhDIB );
-	else if( mhDDB )
-		DeleteObject( mhDDB );
-
-	maSize = Size();
-	mnBitCount = 0;
-}
-
-// ------------------------------------------------------------------
-
 sal_uInt16 WinSalBitmap::ImplGetDIBColorCount( HGLOBAL hDIB )
 {
 	sal_uInt16 nColors = 0;