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/02/05 15:16:19 UTC

svn commit: r1442597 [3/3] - in /openoffice/branches/alg/sysdepgs/main: basegfx/inc/basegfx/polygon/ basegfx/inc/basegfx/tools/ basegfx/prj/ basegfx/source/polygon/ basegfx/source/tools/ drawinglayer/ drawinglayer/inc/drawinglayer/processor2d/ drawingl...

Modified: openoffice/branches/alg/sysdepgs/main/svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg/sysdepgs/main/svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx?rev=1442597&r1=1442596&r2=1442597&view=diff
==============================================================================
--- openoffice/branches/alg/sysdepgs/main/svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx (original)
+++ openoffice/branches/alg/sysdepgs/main/svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx Tue Feb  5 14:16:19 2013
@@ -50,22 +50,25 @@ namespace drawinglayer
 			// Do use createPolygonFromUnitCircle, but let create from first quadrant to mimic old geometry creation.
 			// This is needed to have the same look when stroke is used since the polygon start point defines the
 			// stroke start, too.
-			basegfx::B2DPolygon aUnitOutline(basegfx::tools::createPolygonFromUnitCircle(1));
+            const basegfx::B2DPolygon aUnitOutlinePolygon(basegfx::tools::createPolygonFromUnitCircle(1));
 
-			// scale and move UnitEllipse to UnitObject (-1,-1 1,1) -> (0,0 1,1)
-			const basegfx::B2DHomMatrix aUnitCorrectionMatrix(
-                basegfx::tools::createScaleTranslateB2DHomMatrix(0.5, 0.5, 0.5, 0.5));
+            // also prepare a single PolyPolygon from it to have a single reference
+            const basegfx::B2DPolyPolygon aUnitOutlinePolyPolygon(aUnitOutlinePolygon);
 
-			// apply to the geometry
-			aUnitOutline.transform(aUnitCorrectionMatrix);
+            // create transformation. Scale and move UnitEllipse to 
+            // UnitObject (-1,-1 1,1) -> (0,0 1,1), then multiply with 
+            // given geometry transformation. This avoids modifying the
+            // unit outline polygon, thus all will use the same instance
+            const basegfx::B2DHomMatrix aTransform(
+                getTransform() * basegfx::tools::createScaleTranslateB2DHomMatrix(0.5, 0.5, 0.5, 0.5));
 
 			// add fill
 			if(!getSdrLFSTAttribute().getFill().isDefault())
 			{
 				appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, 
                     createPolyPolygonFillPrimitive(
-                        basegfx::B2DPolyPolygon(aUnitOutline), 
-                        getTransform(), 
+                        aUnitOutlinePolyPolygon, 
+                        aTransform, 
                         getSdrLFSTAttribute().getFill(), 
                         getSdrLFSTAttribute().getFillFloatTransGradient()));
 			}
@@ -77,15 +80,15 @@ namespace drawinglayer
 				appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, 
 					createHiddenGeometryPrimitives2D(
                         false,
-						basegfx::B2DPolyPolygon(aUnitOutline), 
-                        getTransform()));
+						aUnitOutlinePolyPolygon, 
+                        aTransform));
 			}
 			else
 			{
 				appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, 
                     createPolygonLinePrimitive(
-                        aUnitOutline, 
-                        getTransform(), 
+                        aUnitOutlinePolygon, 
+                        aTransform, 
                         getSdrLFSTAttribute().getLine(),
 						attribute::SdrLineStartEndAttribute()));
 			}
@@ -95,8 +98,8 @@ namespace drawinglayer
 			{
 				appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, 
                     createTextPrimitive(
-                        basegfx::B2DPolyPolygon(aUnitOutline), 
-                        getTransform(), 
+                        aUnitOutlinePolyPolygon, 
+                        aTransform, 
                         getSdrLFSTAttribute().getText(), 
                         getSdrLFSTAttribute().getLine(), 
                         false, 
@@ -154,34 +157,40 @@ namespace drawinglayer
 			Primitive2DSequence aRetval;
 
 			// create unit outline polygon
-			basegfx::B2DPolygon aUnitOutline(basegfx::tools::createPolygonFromUnitEllipseSegment(mfStartAngle, mfEndAngle));
+			basegfx::B2DPolygon aUnitOutlinePolygon(
+                basegfx::tools::createPolygonFromUnitEllipseSegment(
+                    getStartAngle(), 
+                    getEndAngle()));
 
-			if(mbCloseSegment)
+			if(getCloseSegment())
 			{
-				if(mbCloseUsingCenter)
+				if(getCloseUsingCenter())
 				{
 					// for compatibility, insert the center point at polygon start to get the same
 					// line stroking pattern as the old painting mechanisms.
-					aUnitOutline.insert(0L, basegfx::B2DPoint(0.0, 0.0));
+					aUnitOutlinePolygon.insert(0, basegfx::B2DPoint(0.0, 0.0));
 				}
 
-				aUnitOutline.setClosed(true);
+				aUnitOutlinePolygon.setClosed(true);
 			}
 
-			// move and scale UnitEllipse to UnitObject (-1,-1 1,1) -> (0,0 1,1)
-			const basegfx::B2DHomMatrix aUnitCorrectionMatrix(
-                basegfx::tools::createScaleTranslateB2DHomMatrix(0.5, 0.5, 0.5, 0.5));
+            // also prepare a single PolyPolygon from it to have a single reference
+            const basegfx::B2DPolyPolygon aUnitOutlinePolyPolygon(aUnitOutlinePolygon);
 
-			// apply to the geometry
-			aUnitOutline.transform(aUnitCorrectionMatrix);
+            // create transformation. Scale and move UnitEllipse to 
+            // UnitObject (-1,-1 1,1) -> (0,0 1,1), then multiply with 
+            // given geometry transformation. This avoids modifying the
+            // unit outline polygon, thus all will use the same instance
+            const basegfx::B2DHomMatrix aTransform(
+                getTransform() * basegfx::tools::createScaleTranslateB2DHomMatrix(0.5, 0.5, 0.5, 0.5));
 
 			// add fill
-			if(!getSdrLFSTAttribute().getFill().isDefault() && aUnitOutline.isClosed())
+			if(!getSdrLFSTAttribute().getFill().isDefault() && aUnitOutlinePolygon.isClosed())
 			{
 				appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, 
                     createPolyPolygonFillPrimitive(
-                        basegfx::B2DPolyPolygon(aUnitOutline), 
-                        getTransform(), 
+                        aUnitOutlinePolyPolygon, 
+                        aTransform, 
                         getSdrLFSTAttribute().getFill(), 
                         getSdrLFSTAttribute().getFillFloatTransGradient()));
 			}
@@ -193,15 +202,15 @@ namespace drawinglayer
 				appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, 
 					createHiddenGeometryPrimitives2D(
                         false,
-						basegfx::B2DPolyPolygon(aUnitOutline), 
-                        getTransform()));
+						aUnitOutlinePolyPolygon, 
+                        aTransform));
 			}
 			else
 			{
 				appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, 
                     createPolygonLinePrimitive(
-                        aUnitOutline, 
-                        getTransform(), 
+                        aUnitOutlinePolygon, 
+                        aTransform, 
                         getSdrLFSTAttribute().getLine(), 
                         getSdrLFSTAttribute().getLineStartEnd()));
 			}
@@ -211,8 +220,8 @@ namespace drawinglayer
 			{
 				appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, 
                     createTextPrimitive(
-                        basegfx::B2DPolyPolygon(aUnitOutline), 
-                        getTransform(), 
+                        aUnitOutlinePolyPolygon, 
+                        aTransform, 
 						getSdrLFSTAttribute().getText(), 
                         getSdrLFSTAttribute().getLine(), 
                         false, 
@@ -252,10 +261,10 @@ namespace drawinglayer
 			{
 				const SdrEllipseSegmentPrimitive2D& rCompare = (SdrEllipseSegmentPrimitive2D&)rPrimitive;
 
-				if(	mfStartAngle == rCompare.mfStartAngle
-					&& mfEndAngle == rCompare.mfEndAngle
-					&& mbCloseSegment == rCompare.mbCloseSegment 
-					&& mbCloseUsingCenter == rCompare.mbCloseUsingCenter)
+				if(	getStartAngle() == rCompare.getStartAngle()
+					&& getEndAngle() == rCompare.getEndAngle()
+					&& getCloseSegment() == rCompare.getCloseSegment() 
+					&& getCloseUsingCenter() == rCompare.getCloseUsingCenter())
 				{
 					return true;
 				}

Modified: openoffice/branches/alg/sysdepgs/main/vcl/inc/vcl/svapp.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg/sysdepgs/main/vcl/inc/vcl/svapp.hxx?rev=1442597&r1=1442596&r2=1442597&view=diff
==============================================================================
--- openoffice/branches/alg/sysdepgs/main/vcl/inc/vcl/svapp.hxx (original)
+++ openoffice/branches/alg/sysdepgs/main/vcl/inc/vcl/svapp.hxx Tue Feb  5 14:16:19 2013
@@ -514,4 +514,16 @@ inline void Application::EndYield()
     PostUserEvent( Link() );
 }
 
+//////////////////////////////////////////////////////////////////////////////
+// support for access to buffered instances of BitmapEx and basegfx Polygons
+// as Gdiplus objects
+#ifdef WNT
+namespace Gdiplus { class Bitmap; class GraphicsPath; }
+namespace basegfx { class B2DPolygon; class B2DPolyPolygon; }
+VCL_DLLPUBLIC boost::shared_ptr< Gdiplus::Bitmap > getBufferedGdiPlusBitmapFromBitmapEx(const BitmapEx& rBitmapEx);
+VCL_DLLPUBLIC boost::shared_ptr< Gdiplus::GraphicsPath > getBufferedGdiPlusGraphicsPathFromB2DPolygon(const basegfx::B2DPolygon& rSource);
+VCL_DLLPUBLIC boost::shared_ptr< Gdiplus::GraphicsPath > getBufferedGdiPlusGraphicsPathFromB2DPolyPolygon(const basegfx::B2DPolyPolygon& rSource);
+#endif
+//////////////////////////////////////////////////////////////////////////////
+
 #endif // _APP_HXX

Added: openoffice/branches/alg/sysdepgs/main/vcl/inc/win/gdiplusobjectbuffer.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg/sysdepgs/main/vcl/inc/win/gdiplusobjectbuffer.hxx?rev=1442597&view=auto
==============================================================================
--- openoffice/branches/alg/sysdepgs/main/vcl/inc/win/gdiplusobjectbuffer.hxx (added)
+++ openoffice/branches/alg/sysdepgs/main/vcl/inc/win/gdiplusobjectbuffer.hxx Tue Feb  5 14:16:19 2013
@@ -0,0 +1,76 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+#ifndef _SV_GDIPLUSOBJECTBUFFER_HXX
+#define _SV_GDIPLUSOBJECTBUFFER_HXX
+
+#include <vcl/timer.hxx>
+#include <basegfx/tools/cmanager.hxx>
+#include <boost/shared_ptr.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// predefines
+
+namespace Gdiplus 
+{ 
+    class Bitmap; 
+    class GraphicsPath;
+}
+
+namespace basegfx
+{
+    class B2DPolygon;
+    class B2DPolyPolygon;
+}
+
+class WinSalBitmap;
+
+//////////////////////////////////////////////////////////////////////////////
+// Helper class to manage Gdiplus::Bitmap instances created from WinSalBitmap
+
+class GdiPlusObjectBuffer : public basegfx::cache::cmanager, public Timer
+{
+private:
+protected:
+public:
+    GdiPlusObjectBuffer();
+    virtual ~GdiPlusObjectBuffer();
+
+    // access to buffered Gdiplus::Bitmap instances created from WinSalBitmap(s)
+    boost::shared_ptr< Gdiplus::Bitmap > getGdiPlusBitmapFromWinSalBitmap(
+        const WinSalBitmap& rBitmapSource, 
+        const WinSalBitmap* pAlphaSource);
+
+    // access to Gdiplus::GraphicsPath instances created from basegfx::B2DPolygon/B2DPolyPolygon
+    boost::shared_ptr< Gdiplus::GraphicsPath > getGdiPlusGraphicsPathFromB2DPolygon(
+        const basegfx::B2DPolygon& rPolygonSource);
+    boost::shared_ptr< Gdiplus::GraphicsPath > getGdiPlusGraphicsPathFromB2DPolyPolygon(
+        const basegfx::B2DPolyPolygon& rPolyPolygonSource);
+
+    virtual void onEmpty();
+    virtual void onFilled();
+    virtual void Timeout();
+};
+
+#endif  // _SV_GDIPLUSOBJECTBUFFER_HXX
+
+//////////////////////////////////////////////////////////////////////////////
+// eof

Propchange: openoffice/branches/alg/sysdepgs/main/vcl/inc/win/gdiplusobjectbuffer.hxx
------------------------------------------------------------------------------
    svn:executable = *

Modified: openoffice/branches/alg/sysdepgs/main/vcl/inc/win/salbmp.h
URL: http://svn.apache.org/viewvc/openoffice/branches/alg/sysdepgs/main/vcl/inc/win/salbmp.h?rev=1442597&r1=1442596&r2=1442597&view=diff
==============================================================================
--- openoffice/branches/alg/sysdepgs/main/vcl/inc/win/salbmp.h (original)
+++ openoffice/branches/alg/sysdepgs/main/vcl/inc/win/salbmp.h Tue Feb  5 14:16:19 2013
@@ -28,6 +28,7 @@
 #include <win/wincomp.hxx>
 #include <salbmp.hxx>
 #include <boost/shared_ptr.hpp>
+#include <basegfx/tools/cacheable.hxx>
 
 // --------------
 // - SalBitmap	-
@@ -37,34 +38,19 @@ struct	BitmapBuffer;
 class	BitmapColor;
 class	BitmapPalette;
 class	SalGraphics;
-namespace Gdiplus { class Bitmap; }
-typedef boost::shared_ptr< Gdiplus::Bitmap > GdiPlusBmpPtr;
 
-class WinSalBitmap : public SalBitmap
+class WinSalBitmap : public SalBitmap, public basegfx::cache::cacheable
 {
 private:
-    friend class GdiPlusBuffer; // allow buffer to remove maGdiPlusBitmap eventually
-
 	Size				maSize;
 	HGLOBAL 			mhDIB;
 	HBITMAP 			mhDDB;
-
-    // the buffered evtl. used Gdiplus::Bitmap instance. It is managed by
-    // GdiPlusBuffer. To make this safe, it is only handed out as shared
-    // pointer; the GdiPlusBuffer may delete the local instance
-    GdiPlusBmpPtr       maGdiPlusBitmap;
-
     sal_uInt16			mnBitCount;
 
-    Gdiplus::Bitmap* ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlphaSource);
-    Gdiplus::Bitmap* ImplCreateGdiPlusBitmap();
-
 public:
-
 	HGLOBAL 			ImplGethDIB() const { return mhDIB; }
 	HBITMAP 			ImplGethDDB() const { return mhDDB; }
     
-    GdiPlusBmpPtr ImplGetGdiPlusBitmap(const WinSalBitmap* pAlphaSource = 0) const;
 
 	static HGLOBAL		ImplCreateDIB( const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal );
 	static HANDLE		ImplCopyDIBOrDDB( HANDLE hHdl, bool bDIB );

Modified: openoffice/branches/alg/sysdepgs/main/vcl/inc/win/saldata.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg/sysdepgs/main/vcl/inc/win/saldata.hxx?rev=1442597&r1=1442596&r2=1442597&view=diff
==============================================================================
--- openoffice/branches/alg/sysdepgs/main/vcl/inc/win/saldata.hxx (original)
+++ openoffice/branches/alg/sysdepgs/main/vcl/inc/win/saldata.hxx Tue Feb  5 14:16:19 2013
@@ -19,19 +19,15 @@
  * 
  *************************************************************/
 
-
-
 #ifndef _SV_SALDATA_HXX
 #define _SV_SALDATA_HXX
 
 #include "osl/module.h"
-
 #include <svdata.hxx>
 #include <salwtype.hxx>
-
 #include <win/wincomp.hxx>
-
-#include <set>  // for hMenu validation
+#include <win/gdiplusobjectbuffer.hxx>
+#include <set>
 #include <map>
 
 class AutoTimer;
@@ -136,6 +132,9 @@ public:
     // for GdiPlus GdiplusStartup/GdiplusShutdown
     ULONG_PTR               gdiplusToken;
 
+    // cache for Gdiplus objects
+    GdiPlusObjectBuffer     maGdiPlusObjectBuffer;
+
     std::set< HMENU >       mhMenuSet;              // keeps track of menu handles created by VCL, used by IsKnownMenuHandle()
     std::map< UINT,USHORT > maVKMap;      // map some dynamic VK_* entries
     oslModule               maDwmLib;

Modified: openoffice/branches/alg/sysdepgs/main/vcl/win/source/app/salinst.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg/sysdepgs/main/vcl/win/source/app/salinst.cxx?rev=1442597&r1=1442596&r2=1442597&view=diff
==============================================================================
--- openoffice/branches/alg/sysdepgs/main/vcl/win/source/app/salinst.cxx (original)
+++ openoffice/branches/alg/sysdepgs/main/vcl/win/source/app/salinst.cxx Tue Feb  5 14:16:19 2013
@@ -470,6 +470,12 @@ void DeInitSalData()
 	CoUninitialize();
 	SalData* pSalData = GetSalData();
 
+    // flush evtl. cached Gdiplus objects
+    if(pSalData)
+    {
+        pSalData->maGdiPlusObjectBuffer.flush();
+    }
+
     // deinit GDIPlus
     if(pSalData)
     {

Modified: openoffice/branches/alg/sysdepgs/main/vcl/win/source/gdi/salbmp.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg/sysdepgs/main/vcl/win/source/gdi/salbmp.cxx?rev=1442597&r1=1442596&r2=1442597&view=diff
==============================================================================
--- openoffice/branches/alg/sysdepgs/main/vcl/win/source/gdi/salbmp.cxx (original)
+++ openoffice/branches/alg/sysdepgs/main/vcl/win/source/gdi/salbmp.cxx Tue Feb  5 14:16:19 2013
@@ -34,15 +34,6 @@
 #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 -
 
@@ -54,138 +45,14 @@ 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() 
-:   maSize(),
+:   basegfx::cache::cacheable(),
+    maSize(),
     mhDIB(0),
     mhDDB(0),
-    maGdiPlusBitmap(),
     mnBitCount(0)
 {
 }
@@ -201,11 +68,6 @@ WinSalBitmap::~WinSalBitmap()
 
 void WinSalBitmap::Destroy()
 {
-    if(maGdiPlusBitmap.get())
-    {
-        aGdiPlusBuffer.remEntry(*this);
-    }
-
     if( mhDIB )
 		GlobalFree( mhDIB );
 	else if( mhDDB )
@@ -217,274 +79,6 @@ void WinSalBitmap::Destroy()
 
 // ------------------------------------------------------------------
 
-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;

Modified: openoffice/branches/alg/sysdepgs/main/vcl/win/source/gdi/salgdi_gdiplus.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/alg/sysdepgs/main/vcl/win/source/gdi/salgdi_gdiplus.cxx?rev=1442597&r1=1442596&r2=1442597&view=diff
==============================================================================
--- openoffice/branches/alg/sysdepgs/main/vcl/win/source/gdi/salgdi_gdiplus.cxx (original)
+++ openoffice/branches/alg/sysdepgs/main/vcl/win/source/gdi/salgdi_gdiplus.cxx Tue Feb  5 14:16:19 2013
@@ -51,137 +51,613 @@
 #endif
 
 #include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <vcl/salbtype.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/bitmapex.hxx>
+#include <win/gdiplusobjectbuffer.hxx>
+#include <impbmp.hxx>
 
-// -----------------------------------------------------------------------
+//////////////////////////////////////////////////////////////////////////////
 
-void impAddB2DPolygonToGDIPlusGraphicsPathReal(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
+class GdiPlusBitmapBufferNode : public basegfx::cache::node
 {
-    sal_uInt32 nCount(rPolygon.count());
+private:
+    boost::shared_ptr< Gdiplus::Bitmap >       maGdiPlusBitmapPtr;
 
-    if(nCount)
+protected:
+    Gdiplus::Bitmap* createGdiPlusBitmap(const WinSalBitmap& rBitmapSource);
+    Gdiplus::Bitmap* createGdiPlusBitmap(const WinSalBitmap& rBitmapSource, const WinSalBitmap& rAlphaSource);
+
+public:
+    GdiPlusBitmapBufferNode(
+        GdiPlusObjectBuffer& rBuffer, 
+        const WinSalBitmap& rBitmapSource, 
+        const WinSalBitmap* pAlphaSource);
+    virtual ~GdiPlusBitmapBufferNode();
+
+    boost::shared_ptr< Gdiplus::Bitmap > getGdiPlusBitmapPtr() const { return maGdiPlusBitmapPtr; }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+class GdiPlusGraphicsPathBufferNode : public basegfx::cache::node
+{
+private:
+    boost::shared_ptr< Gdiplus::GraphicsPath >       maGdiPlusGraphicsPathPtr;
+
+protected:
+    Gdiplus::GraphicsPath* createGdiPlusGraphicsPath(const basegfx::B2DPolygon& rSource);
+    Gdiplus::GraphicsPath* createGdiPlusGraphicsPath(const basegfx::B2DPolyPolygon& rSource);
+
+public:
+    GdiPlusGraphicsPathBufferNode(
+        GdiPlusObjectBuffer& rBuffer, 
+        const basegfx::B2DPolygon& rSource);
+    GdiPlusGraphicsPathBufferNode(
+        GdiPlusObjectBuffer& rBuffer, 
+        const basegfx::B2DPolyPolygon& rSource);
+    virtual ~GdiPlusGraphicsPathBufferNode();
+
+    boost::shared_ptr< Gdiplus::GraphicsPath > getGdiPlusGraphicsPathPtr() const { return maGdiPlusGraphicsPathPtr; }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+GdiPlusObjectBuffer::GdiPlusObjectBuffer()
+:   basegfx::cache::cmanager(30), // keep for 30 seconds
+    Timer()
+{
+    SetTimeout(1000); // one second
+    Stop();
+}
+
+GdiPlusObjectBuffer::~GdiPlusObjectBuffer()
+{
+    Stop();
+}
+
+boost::shared_ptr< Gdiplus::Bitmap > GdiPlusObjectBuffer::getGdiPlusBitmapFromWinSalBitmap(
+    const WinSalBitmap& rBitmapSource, 
+    const WinSalBitmap* pAlphaSource)
+{
+    const Size aSize(rBitmapSource.GetSize());
+
+    if(aSize.Width() && aSize.Height())
     {
-        const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
-        const bool bControls(rPolygon.areControlPointsUsed());
-        basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
-        Gdiplus::PointF aFCurr(Gdiplus::REAL(aCurr.getX()), Gdiplus::REAL(aCurr.getY()));
+        const GdiPlusBitmapBufferNode* pEntry = static_cast< const GdiPlusBitmapBufferNode* >(getEntry(rBitmapSource));
 
-        for(sal_uInt32 a(0); a < nEdgeCount; a++)
+        if(!pEntry)
         {
-	        const sal_uInt32 nNextIndex((a + 1) % nCount);
-	        const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
-	        const Gdiplus::PointF aFNext(Gdiplus::REAL(aNext.getX()), Gdiplus::REAL(aNext.getY()));
+            pEntry = new GdiPlusBitmapBufferNode(*this, rBitmapSource, pAlphaSource);
+        }
+        else
+        {
+            const_cast< GdiPlusBitmapBufferNode* >(pEntry)->touch();
+        }
 
-	        if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
-	        {
-		        const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
-		        const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
+        return pEntry->getGdiPlusBitmapPtr();
+    }
 
-		        rPath.AddBezier(
-			        aFCurr, 
-			        Gdiplus::PointF(Gdiplus::REAL(aCa.getX()), Gdiplus::REAL(aCa.getY())),
-			        Gdiplus::PointF(Gdiplus::REAL(aCb.getX()), Gdiplus::REAL(aCb.getY())),
-			        aFNext);
-	        }
-	        else
-	        {
-		        rPath.AddLine(aFCurr, aFNext);
-	        }
+    return boost::shared_ptr< Gdiplus::Bitmap >();
+}
 
-	        if(a + 1 < nEdgeCount)
-	        {
-		        aFCurr = aFNext;
+boost::shared_ptr< Gdiplus::GraphicsPath > GdiPlusObjectBuffer::getGdiPlusGraphicsPathFromB2DPolygon(
+    const basegfx::B2DPolygon& rPolygonSource)
+{
+    if(rPolygonSource.count())
+    {
+        const GdiPlusGraphicsPathBufferNode* pEntry = static_cast< const GdiPlusGraphicsPathBufferNode* >(getEntry(rPolygonSource.getCacheable()));
 
-			    if(bNoLineJoin)
-			    {
-				    rPath.StartFigure();
-			    }
-	        }
+        if(!pEntry)
+        {
+            pEntry = new GdiPlusGraphicsPathBufferNode(*this, rPolygonSource);
         }
+        else
+        {
+            const_cast< GdiPlusGraphicsPathBufferNode* >(pEntry)->touch();
+        }
+
+        return pEntry->getGdiPlusGraphicsPathPtr();
     }
+
+    return boost::shared_ptr< Gdiplus::GraphicsPath >();
 }
 
-void impAddB2DPolygonToGDIPlusGraphicsPathInteger(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
+boost::shared_ptr< Gdiplus::GraphicsPath > GdiPlusObjectBuffer::getGdiPlusGraphicsPathFromB2DPolyPolygon(
+    const basegfx::B2DPolyPolygon& rPolyPolygonSource)
 {
-    sal_uInt32 nCount(rPolygon.count());
+    if(rPolyPolygonSource.count())
+    {
+        const GdiPlusGraphicsPathBufferNode* pEntry = static_cast< const GdiPlusGraphicsPathBufferNode* >(getEntry(rPolyPolygonSource.getCacheable()));
 
-    if(nCount)
+        if(!pEntry)
+        {
+            pEntry = new GdiPlusGraphicsPathBufferNode(*this, rPolyPolygonSource);
+        }
+        else
+        {
+            const_cast< GdiPlusGraphicsPathBufferNode* >(pEntry)->touch();
+        }
+
+        return pEntry->getGdiPlusGraphicsPathPtr();
+    }
+
+    return boost::shared_ptr< Gdiplus::GraphicsPath >();
+}
+
+void GdiPlusObjectBuffer::onEmpty()
+{
+    Stop();
+}
+
+void GdiPlusObjectBuffer::onFilled()
+{
+    Start();
+}
+
+void GdiPlusObjectBuffer::Timeout()
+{
+    trigger();
+
+    if(!empty())
     {
-        const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
-        const bool bControls(rPolygon.areControlPointsUsed());
-        basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
-        Gdiplus::Point aICurr(INT(aCurr.getX()), INT(aCurr.getY()));
-
-        for(sal_uInt32 a(0); a < nEdgeCount; a++)
-        {
-	        const sal_uInt32 nNextIndex((a + 1) % nCount);
-	        const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
-	        const Gdiplus::Point aINext(INT(aNext.getX()), INT(aNext.getY()));
-
-	        if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
-	        {
-		        const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
-		        const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
-
-		        rPath.AddBezier(
-			        aICurr, 
-			        Gdiplus::Point(INT(aCa.getX()), INT(aCa.getY())),
-			        Gdiplus::Point(INT(aCb.getX()), INT(aCb.getY())),
-			        aINext);
-	        }
-	        else
-	        {
-		        rPath.AddLine(aICurr, aINext);
-	        }
-
-	        if(a + 1 < nEdgeCount)
-	        {
-		        aICurr = aINext;
-
-			    if(bNoLineJoin)
-			    {
-				    rPath.StartFigure();
-			    }
-	        }
+        Start();
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+Gdiplus::Bitmap* GdiPlusBitmapBufferNode::createGdiPlusBitmap(
+    const WinSalBitmap& rBitmapSource)
+{
+    Gdiplus::Bitmap* pRetval(0);
+    WinSalBitmap* pSalRGB = const_cast< WinSalBitmap* >(&rBitmapSource);
+    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;
 }
 
-bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency)
+Gdiplus::Bitmap* GdiPlusBitmapBufferNode::createGdiPlusBitmap(
+    const WinSalBitmap& rBitmapSource, 
+    const WinSalBitmap& rAlphaSource)
 {
-	const sal_uInt32 nCount(rPolyPolygon.count());
+    Gdiplus::Bitmap* pRetval(0);
+    WinSalBitmap* pSalRGB = const_cast< WinSalBitmap* >(&rBitmapSource);
+    WinSalBitmap* pExtraWinSalRGB = 0;
 
-	if(mbBrush && nCount && (fTransparency >= 0.0 && fTransparency < 1.0))
-	{
-		Gdiplus::Graphics aGraphics(getHDC());
-		const sal_uInt8 aTrans((sal_uInt8)255 - (sal_uInt8)basegfx::fround(fTransparency * 255.0));
-		Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maFillColor), SALCOLOR_GREEN(maFillColor), SALCOLOR_BLUE(maFillColor));
-		Gdiplus::SolidBrush aTestBrush(aTestColor);
-		Gdiplus::GraphicsPath aPath;
+    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;
+    }
 
-		for(sal_uInt32 a(0); a < nCount; a++)
-		{
-            if(0 != a)
+    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++)
             {
-                aPath.StartFigure(); // #i101491# not needed for first run
+                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;
             }
+        }
+    }
 
-			impAddB2DPolygonToGDIPlusGraphicsPathReal(aPath, rPolyPolygon.getB2DPolygon(a), false);
-            aPath.CloseFigure();
-		}
+    if(pExtraA)
+    {
+        delete pExtraA;
+    }
+    else
+    {
+        pSalA->ReleaseBuffer(pA, true);
+    }
 
-        if(getAntiAliasB2DDraw())
+    if(pExtraWinSalA)
+    {
+        delete pExtraWinSalA;
+    }
+
+    if(pExtraRGB)
+    {
+        delete pExtraRGB;
+    }
+    else
+    {
+        pSalRGB->ReleaseBuffer(pRGB, true);
+    }
+
+    if(pExtraWinSalRGB)
+    {
+        delete pExtraWinSalRGB;
+    }
+
+    return pRetval;
+}
+
+GdiPlusBitmapBufferNode::GdiPlusBitmapBufferNode(
+    GdiPlusObjectBuffer& rBuffer, 
+    const WinSalBitmap& rBitmapSource, 
+    const WinSalBitmap* pAlphaSource)
+:   basegfx::cache::node(rBuffer, rBitmapSource),
+    maGdiPlusBitmapPtr()
+{
+    if(pAlphaSource)
+    {
+        maGdiPlusBitmapPtr.reset(createGdiPlusBitmap(rBitmapSource, *pAlphaSource));
+    }
+    else
+    {
+        maGdiPlusBitmapPtr.reset(createGdiPlusBitmap(rBitmapSource));
+    }
+}
+
+GdiPlusBitmapBufferNode::~GdiPlusBitmapBufferNode()
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+    void addGdiPlusGraphicsPath(
+        Gdiplus::GraphicsPath* pRetval, const basegfx::B2DPolygon& rSource,
+        bool bForceSingleEdges)
+    {
+        const sal_uInt32 nCount(rSource.count());
+
+        if(nCount)
         {
-            aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+            const sal_uInt32 nEdgeCount(rSource.isClosed() ? nCount : nCount - 1);
+            const bool bControls(rSource.areControlPointsUsed());
+            basegfx::B2DPoint aCurr(rSource.getB2DPoint(0));
+            Gdiplus::PointF aFCurr(Gdiplus::REAL(aCurr.getX()), Gdiplus::REAL(aCurr.getY()));
+
+            for(sal_uInt32 a(0); a < nEdgeCount; a++)
+            {
+                const sal_uInt32 nNextIndex((a + 1) % nCount);
+                const basegfx::B2DPoint aNext(rSource.getB2DPoint(nNextIndex));
+                const Gdiplus::PointF aFNext(Gdiplus::REAL(aNext.getX()), Gdiplus::REAL(aNext.getY()));
+
+                if(bControls && (rSource.isNextControlPointUsed(a) || rSource.isPrevControlPointUsed(nNextIndex)))
+                {
+                    const basegfx::B2DPoint aCa(rSource.getNextControlPoint(a));
+                    const basegfx::B2DPoint aCb(rSource.getPrevControlPoint(nNextIndex));
+
+                    pRetval->AddBezier(
+                        aFCurr, 
+                        Gdiplus::PointF(Gdiplus::REAL(aCa.getX()), Gdiplus::REAL(aCa.getY())),
+                        Gdiplus::PointF(Gdiplus::REAL(aCb.getX()), Gdiplus::REAL(aCb.getY())),
+                        aFNext);
+                }
+                else
+                {
+                    pRetval->AddLine(aFCurr, aFNext);
+                }
+
+                if(a + 1 < nEdgeCount)
+                {
+                    aFCurr = aFNext;
+
+                    if(bForceSingleEdges)
+                    {
+                        pRetval->StartFigure();
+                    }
+                }
+            }
         }
-        else
+    }
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+
+Gdiplus::GraphicsPath* GdiPlusGraphicsPathBufferNode::createGdiPlusGraphicsPath(const basegfx::B2DPolygon& rSource)
+{
+    Gdiplus::GraphicsPath* pRetval = 0;
+    const sal_uInt32 nCount(rSource.count());
+
+    if(nCount)
+    {
+        pRetval = new Gdiplus::GraphicsPath;
+
+        addGdiPlusGraphicsPath(pRetval, rSource, false);
+
+        if(rSource.isClosed())
+        {
+            pRetval->CloseFigure();
+        }
+    }
+
+    return pRetval;
+}
+
+Gdiplus::GraphicsPath* GdiPlusGraphicsPathBufferNode::createGdiPlusGraphicsPath(const basegfx::B2DPolyPolygon& rSource)
+{
+    Gdiplus::GraphicsPath* pRetval = 0;
+    const sal_uInt32 nCount(rSource.count());
+
+    if(nCount)
+    {
+        pRetval = new Gdiplus::GraphicsPath;
+        bool bFirst(true);
+
+        for(sal_uInt32 a(0); a < nCount; a++)
         {
-    		aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
+            const basegfx::B2DPolygon aPolygon(rSource.getB2DPolygon(a));
+
+            // try to get an already existing and buffered Gdiplus::GraphicsPath from the single B2DPolygon
+            boost::shared_ptr< Gdiplus::GraphicsPath > aSource(GetSalData()->maGdiPlusObjectBuffer.getGdiPlusGraphicsPathFromB2DPolygon(aPolygon));
+
+            if(aSource.get())
+            {
+                if(bFirst)
+                {
+                    pRetval->StartFigure();
+                    bFirst = false;
+                }
+
+                // concatenate partial path
+                pRetval->AddPath(aSource.get(), FALSE);
+
+                // for PolyPolygon, always close
+                pRetval->CloseFigure();
+            }
         }
+    }
+
+    return pRetval;
+}
+
+GdiPlusGraphicsPathBufferNode::GdiPlusGraphicsPathBufferNode(
+    GdiPlusObjectBuffer& rBuffer, 
+    const basegfx::B2DPolygon& rSource)
+:   basegfx::cache::node(rBuffer, rSource.getCacheable()),
+    maGdiPlusGraphicsPathPtr()
+{
+    maGdiPlusGraphicsPathPtr.reset(createGdiPlusGraphicsPath(rSource));
+}
+
+GdiPlusGraphicsPathBufferNode::GdiPlusGraphicsPathBufferNode(
+    GdiPlusObjectBuffer& rBuffer, 
+    const basegfx::B2DPolyPolygon& rSource)
+:   basegfx::cache::node(rBuffer, rSource.getCacheable()),
+    maGdiPlusGraphicsPathPtr()
+{
+    maGdiPlusGraphicsPathPtr.reset(createGdiPlusGraphicsPath(rSource));
+}
+
+GdiPlusGraphicsPathBufferNode::~GdiPlusGraphicsPathBufferNode()
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+VCL_DLLPUBLIC boost::shared_ptr< Gdiplus::Bitmap > getBufferedGdiPlusBitmapFromBitmapEx(
+    const BitmapEx& rBitmapEx)
+{
+    const SalBitmap& rSalSrcBmp = *rBitmapEx.ImplGetBitmapImpBitmap()->ImplGetSalBitmap();
+    const SalBitmap* pSalAlphaBmp = 0;
 
-		aGraphics.FillPath(&aTestBrush, &aPath);
-	}
+    if(rBitmapEx.IsTransparent())
+    {
+        pSalAlphaBmp = rBitmapEx.ImplGetMaskImpBitmap()->ImplGetSalBitmap();
+    }
+
+    return GetSalData()->maGdiPlusObjectBuffer.getGdiPlusBitmapFromWinSalBitmap(
+        static_cast< const WinSalBitmap& >(rSalSrcBmp), 
+        static_cast< const WinSalBitmap* >(pSalAlphaBmp));
+}
 
- 	return true;
+VCL_DLLPUBLIC boost::shared_ptr< Gdiplus::GraphicsPath > getBufferedGdiPlusGraphicsPathFromB2DPolygon(
+    const basegfx::B2DPolygon& rSource)
+{
+    return GetSalData()->maGdiPlusObjectBuffer.getGdiPlusGraphicsPathFromB2DPolygon(rSource);
+}
+
+VCL_DLLPUBLIC boost::shared_ptr< Gdiplus::GraphicsPath > getBufferedGdiPlusGraphicsPathFromB2DPolyPolygon(
+    const basegfx::B2DPolyPolygon& rSource)
+{
+    return GetSalData()->maGdiPlusObjectBuffer.getGdiPlusGraphicsPathFromB2DPolyPolygon(rSource);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency)
+{
+    const sal_uInt32 nCount(rPolyPolygon.count());
+
+    if(mbBrush && nCount && (fTransparency >= 0.0 && fTransparency < 1.0))
+    {
+        const boost::shared_ptr< Gdiplus::GraphicsPath > aPath(getBufferedGdiPlusGraphicsPathFromB2DPolyPolygon(rPolyPolygon));
+
+        if(aPath.get())
+        {
+            Gdiplus::Graphics aGraphics(getHDC());
+            const sal_uInt8 aTrans((sal_uInt8)255 - (sal_uInt8)basegfx::fround(fTransparency * 255.0));
+            Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maFillColor), SALCOLOR_GREEN(maFillColor), SALCOLOR_BLUE(maFillColor));
+            Gdiplus::SolidBrush aTestBrush(aTestColor);
+
+            if(getAntiAliasB2DDraw())
+            {
+                aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+            }
+            else
+            {
+                aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
+            }
+
+            aGraphics.FillPath(&aTestBrush, aPath.get());
+        }
+    }
+
+    return true;
 }
 
 bool WinSalGraphics::drawPolyLine( 
@@ -193,94 +669,104 @@ bool WinSalGraphics::drawPolyLine( 
 {
     const sal_uInt32 nCount(rPolygon.count());
 
-	if(mbPen && nCount)
-	{
-		Gdiplus::Graphics aGraphics(getHDC());
-		const sal_uInt8 aTrans = (sal_uInt8)basegfx::fround( 255 * (1.0 - fTransparency) );
-		Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor));
-		Gdiplus::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX()));
-		Gdiplus::GraphicsPath aPath;
-		bool bNoLineJoin(false);
-
-		switch(eLineJoin)
-		{
-			default : // basegfx::B2DLINEJOIN_NONE :
-			{
-				if(basegfx::fTools::more(rLineWidths.getX(), 0.0))
-				{
-					bNoLineJoin = true;
-				}
-				break;
-			}
-			case basegfx::B2DLINEJOIN_BEVEL :
-			{
-				aTestPen.SetLineJoin(Gdiplus::LineJoinBevel);
-				break;
-			}
-			case basegfx::B2DLINEJOIN_MIDDLE :
-			case basegfx::B2DLINEJOIN_MITER :
-			{
-				const Gdiplus::REAL aMiterLimit(15.0);
-				aTestPen.SetMiterLimit(aMiterLimit);
-				aTestPen.SetLineJoin(Gdiplus::LineJoinMiter);
-				break;
-			}
-			case basegfx::B2DLINEJOIN_ROUND :
-			{
-				aTestPen.SetLineJoin(Gdiplus::LineJoinRound);
-				break;
-			}
-		}
+    if(mbPen && nCount)
+    {
+        boost::shared_ptr< Gdiplus::GraphicsPath > aPath;
+        const sal_uInt8 aTrans = (sal_uInt8)basegfx::fround( 255 * (1.0 - fTransparency) );
+        Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor));
+        Gdiplus::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX()));
+        bool bNoLineJoin(false);
 
-        switch(eLineCap)
+        switch(eLineJoin)
         {
-            default: /*com::sun::star::drawing::LineCap_BUTT*/
+            default : // basegfx::B2DLINEJOIN_NONE :
+            {
+                if(basegfx::fTools::more(rLineWidths.getX(), 0.0))
+                {
+                    bNoLineJoin = true;
+                }
+                break;
+            }
+            case basegfx::B2DLINEJOIN_BEVEL :
             {
-                // nothing to do
+                aTestPen.SetLineJoin(Gdiplus::LineJoinBevel);
                 break;
             }
-            case com::sun::star::drawing::LineCap_ROUND:
+            case basegfx::B2DLINEJOIN_MIDDLE :
+            case basegfx::B2DLINEJOIN_MITER :
             {
-                aTestPen.SetStartCap(Gdiplus::LineCapRound);
-                aTestPen.SetEndCap(Gdiplus::LineCapRound);
+                const Gdiplus::REAL aMiterLimit(15.0);
+                aTestPen.SetMiterLimit(aMiterLimit);
+                aTestPen.SetLineJoin(Gdiplus::LineJoinMiter);
                 break;
             }
-            case com::sun::star::drawing::LineCap_SQUARE:
+            case basegfx::B2DLINEJOIN_ROUND :
             {
-                aTestPen.SetStartCap(Gdiplus::LineCapSquare);
-                aTestPen.SetEndCap(Gdiplus::LineCapSquare);
+                aTestPen.SetLineJoin(Gdiplus::LineJoinRound);
                 break;
             }
         }
 
-		if(nCount > 250 && basegfx::fTools::more(rLineWidths.getX(), 1.5))
+        if(bNoLineJoin)
         {
-    		impAddB2DPolygonToGDIPlusGraphicsPathInteger(aPath, rPolygon, bNoLineJoin);
+            // need to create a special version to support the line join mode 'none'. This
+            // is simply done by creating single edges, so no line joins will be visualized
+            Gdiplus::GraphicsPath* pNew = new Gdiplus::GraphicsPath;
+
+            addGdiPlusGraphicsPath(pNew, rPolygon, true);
+
+            if(rPolygon.isClosed())
+            {
+                pNew->CloseFigure();
+            }
+
+            aPath.reset(pNew);
         }
         else
         {
-    		impAddB2DPolygonToGDIPlusGraphicsPathReal(aPath, rPolygon, bNoLineJoin);
+            // use the buffered common geometry version
+            aPath = getBufferedGdiPlusGraphicsPathFromB2DPolygon(rPolygon);
         }
 
-        if(rPolygon.isClosed() && !bNoLineJoin)
-        {
-            // #i101491# needed to create the correct line joins
-            aPath.CloseFigure();
-        }
-		
-        if(getAntiAliasB2DDraw())
+        if(aPath.get())
         {
-    		aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
-        }
-        else
-        {
-    		aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
-        }
+            Gdiplus::Graphics aGraphics(getHDC());
+
+            switch(eLineCap)
+            {
+                default: /*com::sun::star::drawing::LineCap_BUTT*/
+                {
+                    // nothing to do
+                    break;
+                }
+                case com::sun::star::drawing::LineCap_ROUND:
+                {
+                    aTestPen.SetStartCap(Gdiplus::LineCapRound);
+                    aTestPen.SetEndCap(Gdiplus::LineCapRound);
+                    break;
+                }
+                case com::sun::star::drawing::LineCap_SQUARE:
+                {
+                    aTestPen.SetStartCap(Gdiplus::LineCapSquare);
+                    aTestPen.SetEndCap(Gdiplus::LineCapSquare);
+                    break;
+                }
+            }
 
-		aGraphics.DrawPath(&aTestPen, &aPath);
-	}
+            if(getAntiAliasB2DDraw())
+            {
+                aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+            }
+            else
+            {
+                aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
+            }
+
+            aGraphics.DrawPath(&aTestPen, aPath.get());
+        }
+    }
 
-	return true;
+    return true;
 }
 
 // -----------------------------------------------------------------------
@@ -354,7 +840,9 @@ bool WinSalGraphics::tryDrawBitmapGdiPlu
     if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight)
     {
         const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap);
-        GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap());
+        boost::shared_ptr< Gdiplus::Bitmap > aARGB(GetSalData()->maGdiPlusObjectBuffer.getGdiPlusBitmapFromWinSalBitmap(
+            rSalBitmap,
+            0));
 
         if(aARGB.get())
         {
@@ -388,7 +876,9 @@ bool WinSalGraphics::drawAlphaBitmap( 
     {
         const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap);
         const WinSalBitmap& rSalAlpha = static_cast< const WinSalBitmap& >(rAlphaBmp);
-        GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(&rSalAlpha));
+        boost::shared_ptr< Gdiplus::Bitmap > aARGB(GetSalData()->maGdiPlusObjectBuffer.getGdiPlusBitmapFromWinSalBitmap(
+            rSalBitmap, 
+            &rSalAlpha));
 
         if(aARGB.get())
         {
@@ -424,7 +914,9 @@ bool WinSalGraphics::drawTransformedBitm
 {
     const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSourceBitmap);
     const WinSalBitmap* pSalAlpha = static_cast< const WinSalBitmap* >(pAlphaBitmap);
-    GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(pSalAlpha));
+    boost::shared_ptr< Gdiplus::Bitmap > aARGB(GetSalData()->maGdiPlusObjectBuffer.getGdiPlusBitmapFromWinSalBitmap(
+        rSalBitmap, 
+        pSalAlpha));
 
     if(aARGB.get())
     {