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())
{