summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2013-07-12 18:51:26 +0200
committerStephan Bergmann <sbergman@redhat.com>2013-07-12 18:51:26 +0200
commitdd547e4a8c1895aa89e699810323c933d9ac415b (patch)
tree4419e9d099ac6f9199d916aa1ba764e3c7c52cec
parent333b7fb38153ae90bcbcc1348c8db698ba207331 (diff)
Fix headless mode glyph cache memory handling
...the original code was riddled with errors. It leaked memory, which if it didn't it would have deleted multiple times. Change-Id: Ic70b425fac02ef894e35b3dc15039d217f8870f5
-rw-r--r--vcl/generic/glyphs/gcach_ftyp.cxx21
-rw-r--r--vcl/generic/glyphs/gcach_rbmp.cxx25
-rw-r--r--vcl/generic/glyphs/glyphcache.cxx6
-rw-r--r--vcl/headless/svptext.cxx45
-rw-r--r--vcl/inc/generic/glyphcache.hxx27
5 files changed, 55 insertions, 69 deletions
diff --git a/vcl/generic/glyphs/gcach_ftyp.cxx b/vcl/generic/glyphs/gcach_ftyp.cxx
index 29c88203517f..979be11377c5 100644
--- a/vcl/generic/glyphs/gcach_ftyp.cxx
+++ b/vcl/generic/glyphs/gcach_ftyp.cxx
@@ -650,7 +650,6 @@ ImplFontEntry* ImplFTSFontData::CreateFontInstance( FontSelectPattern& rFSD ) co
ServerFont::ServerFont( const FontSelectPattern& rFSD, FtFontInfo* pFI )
: maGlyphList( 0),
maFontSelData(rFSD),
- mnExtInfo(0),
mnRefCount(1),
mnBytesUsed( sizeof(ServerFont) ),
mpPrevGCFont( NULL ),
@@ -1420,20 +1419,19 @@ bool ServerFont::GetGlyphBitmap1( int nGlyphIndex, RawBitmap& rRawBitmap ) const
if( rRawBitmap.mnAllocated < nNeededSize )
{
- delete[] rRawBitmap.mpBits;
rRawBitmap.mnAllocated = 2*nNeededSize;
- rRawBitmap.mpBits = new unsigned char[ rRawBitmap.mnAllocated ];
+ rRawBitmap.mpBits.reset(new unsigned char[ rRawBitmap.mnAllocated ]);
}
if( !mbArtBold || pFTEmbolden )
{
- memcpy( rRawBitmap.mpBits, rBitmapFT.buffer, nNeededSize );
+ memcpy( rRawBitmap.mpBits.get(), rBitmapFT.buffer, nNeededSize );
}
else
{
- memset( rRawBitmap.mpBits, 0, nNeededSize );
+ memset( rRawBitmap.mpBits.get(), 0, nNeededSize );
const unsigned char* pSrcLine = rBitmapFT.buffer;
- unsigned char* pDstLine = rRawBitmap.mpBits;
+ unsigned char* pDstLine = rRawBitmap.mpBits.get();
for( int h = rRawBitmap.mnHeight; --h >= 0; )
{
memcpy( pDstLine, pSrcLine, rBitmapFT.pitch );
@@ -1441,7 +1439,7 @@ bool ServerFont::GetGlyphBitmap1( int nGlyphIndex, RawBitmap& rRawBitmap ) const
pSrcLine += rBitmapFT.pitch;
}
- unsigned char* p = rRawBitmap.mpBits;
+ unsigned char* p = rRawBitmap.mpBits.get();
for( sal_uLong y=0; y < rRawBitmap.mnHeight; y++ )
{
unsigned char nLastByte = 0;
@@ -1549,13 +1547,12 @@ bool ServerFont::GetGlyphBitmap8( int nGlyphIndex, RawBitmap& rRawBitmap ) const
const sal_uLong nNeededSize = rRawBitmap.mnScanlineSize * rRawBitmap.mnHeight;
if( rRawBitmap.mnAllocated < nNeededSize )
{
- delete[] rRawBitmap.mpBits;
rRawBitmap.mnAllocated = 2*nNeededSize;
- rRawBitmap.mpBits = new unsigned char[ rRawBitmap.mnAllocated ];
+ rRawBitmap.mpBits.reset(new unsigned char[ rRawBitmap.mnAllocated ]);
}
const unsigned char* pSrc = rBitmapFT.buffer;
- unsigned char* pDest = rRawBitmap.mpBits;
+ unsigned char* pDest = rRawBitmap.mpBits.get();
if( !bEmbedded )
{
for( int y = rRawBitmap.mnHeight, x; --y >= 0 ; )
@@ -1585,7 +1582,7 @@ bool ServerFont::GetGlyphBitmap8( int nGlyphIndex, RawBitmap& rRawBitmap ) const
if( mbArtBold && !pFTEmbolden )
{
// overlay with glyph image shifted by one left pixel
- unsigned char* p = rRawBitmap.mpBits;
+ unsigned char* p = rRawBitmap.mpBits.get();
for( sal_uLong y=0; y < rRawBitmap.mnHeight; y++ )
{
unsigned char nLastByte = 0;
@@ -1601,7 +1598,7 @@ bool ServerFont::GetGlyphBitmap8( int nGlyphIndex, RawBitmap& rRawBitmap ) const
if( !bEmbedded && mbUseGamma )
{
- unsigned char* p = rRawBitmap.mpBits;
+ unsigned char* p = rRawBitmap.mpBits.get();
for( sal_uLong y=0; y < rRawBitmap.mnHeight; y++ )
{
for( sal_uLong x=0; x < rRawBitmap.mnWidth; x++ )
diff --git a/vcl/generic/glyphs/gcach_rbmp.cxx b/vcl/generic/glyphs/gcach_rbmp.cxx
index 684f8869328d..0efe54cef3e0 100644
--- a/vcl/generic/glyphs/gcach_rbmp.cxx
+++ b/vcl/generic/glyphs/gcach_rbmp.cxx
@@ -23,16 +23,12 @@
RawBitmap::RawBitmap()
-: mpBits(0), mnAllocated(0)
+: mnAllocated(0)
{}
RawBitmap::~RawBitmap()
-{
- delete[] mpBits;
- mpBits = 0;
- mnAllocated = 0;
-}
+{}
// used by 90 and 270 degree rotations on 8 bit deep bitmaps
@@ -171,7 +167,7 @@ bool RawBitmap::Rotate( int nAngle )
mnYOffset = -(mnYOffset + mnHeight);
if( mnBitCount == 8 )
{
- ImplRotate8_180( mpBits, mnWidth, mnHeight, mnScanlineSize-mnWidth );
+ ImplRotate8_180( mpBits.get(), mnWidth, mnHeight, mnScanlineSize-mnWidth );
return true;
}
nNewWidth = mnWidth;
@@ -203,7 +199,7 @@ bool RawBitmap::Rotate( int nAngle )
{
case 1800: // rotate by 180 degrees
// we know we only need to deal with 1 bit depth
- ImplRotate1_180( pBuf, mpBits + mnHeight * mnScanlineSize,
+ ImplRotate1_180( pBuf, mpBits.get() + mnHeight * mnScanlineSize,
mnWidth, mnHeight, mnScanlineSize - (mnWidth + 7) / 8 );
break;
case +900: // rotate left by 90 degrees
@@ -211,11 +207,11 @@ bool RawBitmap::Rotate( int nAngle )
mnXOffset = mnYOffset;
mnYOffset = -nNewHeight - i;
if( mnBitCount == 8 )
- ImplRotate8_90( pBuf, mpBits + mnWidth - 1,
+ ImplRotate8_90( pBuf, mpBits.get() + mnWidth - 1,
nNewWidth, nNewHeight, +mnScanlineSize, -1-mnHeight*mnScanlineSize,
nNewScanlineSize - nNewWidth );
else
- ImplRotate1_90( pBuf, mpBits + (mnWidth - 1) / 8,
+ ImplRotate1_90( pBuf, mpBits.get() + (mnWidth - 1) / 8,
nNewWidth, nNewHeight, +mnScanlineSize,
(-mnWidth & 7), +1, nNewScanlineSize - (nNewWidth + 7) / 8 );
break;
@@ -225,11 +221,11 @@ bool RawBitmap::Rotate( int nAngle )
mnXOffset = -(nNewWidth + mnYOffset);
mnYOffset = i;
if( mnBitCount == 8 )
- ImplRotate8_90( pBuf, mpBits + mnScanlineSize * (mnHeight-1),
+ ImplRotate8_90( pBuf, mpBits.get() + mnScanlineSize * (mnHeight-1),
nNewWidth, nNewHeight, -mnScanlineSize, +1+mnHeight*mnScanlineSize,
nNewScanlineSize - nNewWidth );
else
- ImplRotate1_90( pBuf, mpBits + mnScanlineSize * (mnHeight-1),
+ ImplRotate1_90( pBuf, mpBits.get() + mnScanlineSize * (mnHeight-1),
nNewWidth, nNewHeight, -mnScanlineSize,
+7, -1, nNewScanlineSize - (nNewWidth + 7) / 8 );
break;
@@ -241,13 +237,12 @@ bool RawBitmap::Rotate( int nAngle )
if( nBufSize < mnAllocated )
{
- memcpy( mpBits, pBuf, nBufSize );
+ memcpy( mpBits.get(), pBuf, nBufSize );
delete[] pBuf;
}
else
{
- delete[] mpBits;
- mpBits = pBuf;
+ mpBits.reset(pBuf);
mnAllocated = nBufSize;
}
diff --git a/vcl/generic/glyphs/glyphcache.cxx b/vcl/generic/glyphs/glyphcache.cxx
index a32b88fd82a0..43c628dd1688 100644
--- a/vcl/generic/glyphs/glyphcache.cxx
+++ b/vcl/generic/glyphs/glyphcache.cxx
@@ -315,9 +315,9 @@ void GlyphCache::GrowNotify()
}
-inline void GlyphCache::RemovingGlyph( ServerFont& rSF, GlyphData& rGD, int nGlyphIndex )
+inline void GlyphCache::RemovingGlyph( GlyphData& rGD )
{
- mrPeer.RemovingGlyph( rSF, rGD, nGlyphIndex );
+ mrPeer.RemovingGlyph( rGD );
mnBytesUsed -= sizeof( GlyphData );
--mnGlyphCount;
}
@@ -372,7 +372,7 @@ void ServerFont::GarbageCollect( long nMinLruIndex )
{
OSL_ASSERT( mnBytesUsed >= sizeof(GlyphData) );
mnBytesUsed -= sizeof( GlyphData );
- GlyphCache::GetInstance().RemovingGlyph( *this, rGD, it->first );
+ GlyphCache::GetInstance().RemovingGlyph( rGD );
maGlyphList.erase( it );
it_next = maGlyphList.begin();
}
diff --git a/vcl/headless/svptext.cxx b/vcl/headless/svptext.cxx
index bbe38f465648..ff316039ac6f 100644
--- a/vcl/headless/svptext.cxx
+++ b/vcl/headless/svptext.cxx
@@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include "sal/config.h"
+
+#include <cassert>
+
#include <basegfx/range/b2drange.hxx>
#include <basegfx/range/b2ibox.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
@@ -50,7 +54,7 @@ public:
protected:
virtual void RemovingFont( ServerFont& );
- virtual void RemovingGlyph( ServerFont&, GlyphData&, int nGlyphIndex );
+ virtual void RemovingGlyph( GlyphData& );
class SvpGcpHelper
{
@@ -113,14 +117,14 @@ BitmapDeviceSharedPtr SvpGlyphPeer::GetGlyphBmp( ServerFont& rServerFont,
int nGlyphIndex, basebmp::Format nBmpFormat, B2IPoint& rTargetPos )
{
GlyphData& rGlyphData = rServerFont.GetGlyphData( nGlyphIndex );
- SvpGcpHelper* pGcpHelper = (SvpGcpHelper*)rGlyphData.ExtDataRef().mpData;
- // nothing to do if the GlyphPeer hasn't allocated resources for the glyph
if( rGlyphData.ExtDataRef().meInfo != nBmpFormat )
{
- if( rGlyphData.ExtDataRef().meInfo == FORMAT_NONE )
+ SvpGcpHelper* pGcpHelper = static_cast<SvpGcpHelper*>(
+ rGlyphData.ExtDataRef().mpData);
+ bool bNew = pGcpHelper == 0;
+ if( bNew )
pGcpHelper = new SvpGcpHelper;
- RawBitmap& rRawBitmap = pGcpHelper->maRawBitmap;
// get glyph bitmap in matching format
bool bFound = false;
@@ -143,22 +147,28 @@ BitmapDeviceSharedPtr SvpGlyphPeer::GetGlyphBmp( ServerFont& rServerFont,
// return .notdef glyph if needed
if( !bFound && (nGlyphIndex != 0) )
{
- delete pGcpHelper;
+ if( bNew )
+ delete pGcpHelper;
return GetGlyphBmp( rServerFont, 0, nBmpFormat, rTargetPos );
}
// construct alpha mask from raw bitmap
- const B2IVector aSize( rRawBitmap.mnScanlineSize, rRawBitmap.mnHeight );
+ const B2IVector aSize(
+ pGcpHelper->maRawBitmap.mnScanlineSize,
+ pGcpHelper->maRawBitmap.mnHeight );
if( aSize.getX() && aSize.getY() )
{
static PaletteMemorySharedVector aDummyPAL;
- RawMemorySharedArray aRawPtr( rRawBitmap.mpBits );
- pGcpHelper->maBitmapDev = createBitmapDevice( aSize, true, nBmpFormat, aRawPtr, aDummyPAL );
+ pGcpHelper->maBitmapDev = createBitmapDevice( aSize, true, nBmpFormat, pGcpHelper->maRawBitmap.mpBits, aDummyPAL );
}
- rServerFont.SetExtended( nBmpFormat, (void*)pGcpHelper );
+ rGlyphData.ExtDataRef().meInfo = nBmpFormat;
+ rGlyphData.ExtDataRef().mpData = pGcpHelper;
}
+ SvpGcpHelper* pGcpHelper = static_cast<SvpGcpHelper*>(
+ rGlyphData.ExtDataRef().mpData);
+ assert(pGcpHelper != 0);
rTargetPos += B2IPoint( pGcpHelper->maRawBitmap.mnXOffset, pGcpHelper->maRawBitmap.mnYOffset );
return pGcpHelper->maBitmapDev;
}
@@ -170,16 +180,13 @@ void SvpGlyphPeer::RemovingFont( ServerFont& )
}
-void SvpGlyphPeer::RemovingGlyph( ServerFont&, GlyphData& rGlyphData, int /*nGlyphIndex*/ )
+void SvpGlyphPeer::RemovingGlyph( GlyphData& rGlyphData )
{
- if( rGlyphData.ExtDataRef().mpData != 0 )
- {
- // release the glyph related resources
- DBG_ASSERT( (rGlyphData.ExtDataRef().meInfo <= FORMAT_MAX), "SVP::RG() invalid alpha format" );
- SvpGcpHelper* pGcpHelper = (SvpGcpHelper*)rGlyphData.ExtDataRef().mpData;
- delete[] pGcpHelper->maRawBitmap.mpBits;
- delete pGcpHelper;
- }
+ SvpGcpHelper* pGcpHelper = static_cast<SvpGcpHelper*>(
+ rGlyphData.ExtDataRef().mpData);
+ rGlyphData.ExtDataRef().meInfo = basebmp::FORMAT_NONE;
+ rGlyphData.ExtDataRef().mpData = 0;
+ delete pGcpHelper;
}
diff --git a/vcl/inc/generic/glyphcache.hxx b/vcl/inc/generic/glyphcache.hxx
index 1457dd52dd3a..d33aee125053 100644
--- a/vcl/inc/generic/glyphcache.hxx
+++ b/vcl/inc/generic/glyphcache.hxx
@@ -34,6 +34,7 @@ struct ImplKernPairData;
class ImplFontOptions;
#include <tools/gen.hxx>
+#include <basebmp/bitmapdevice.hxx>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include <boost/shared_ptr.hpp>
@@ -90,7 +91,7 @@ private:
friend class ServerFont;
// used by ServerFont class only
void AddedGlyph( ServerFont&, GlyphData& );
- void RemovingGlyph( ServerFont&, GlyphData&, int nGlyphIndex );
+ void RemovingGlyph( GlyphData& );
void UsingGlyph( ServerFont&, GlyphData& );
void GrowNotify();
@@ -139,7 +140,9 @@ private:
// -----------------------------------------------------------------------
// the glyph specific data needed by a GlyphCachePeer is usually trivial,
-// not attaching it to the corresponding GlyphData would be overkill
+// not attaching it to the corresponding GlyphData would be overkill;
+// this is currently only used by the headless (aka svp) plugin, where meInfo is
+// basebmp::Format and mpData is SvpGcpHelper*
struct ExtGlyphData
{
int meInfo;
@@ -219,10 +222,6 @@ public:
bool GetGlyphBitmap1( int nGlyphIndex, RawBitmap& ) const;
bool GetGlyphBitmap8( int nGlyphIndex, RawBitmap& ) const;
- void SetExtended( int nInfo, void* ppVoid );
- int GetExtInfo() { return mnExtInfo; }
- void* GetExtPointer() { return mpExtData; }
-
private:
friend class GlyphCache;
friend class ServerFontLayout;
@@ -248,10 +247,6 @@ private:
const FontSelectPattern maFontSelData;
- // info for GlyphcachePeer
- int mnExtInfo;
- void* mpExtData;
-
// used by GlyphCache for cache LRU algorithm
mutable long mnRefCount;
mutable sal_uLong mnBytesUsed;
@@ -351,7 +346,7 @@ protected:
public:
sal_Int32 GetByteCount() const { return mnBytesUsed; }
virtual void RemovingFont( ServerFont& ) {}
- virtual void RemovingGlyph( ServerFont&, GlyphData&, int ) {}
+ virtual void RemovingGlyph( GlyphData& ) {}
protected:
sal_Int32 mnBytesUsed;
@@ -367,7 +362,7 @@ public:
bool Rotate( int nAngle );
public:
- unsigned char* mpBits;
+ basebmp::RawMemorySharedArray mpBits;
sal_uLong mnAllocated;
sal_uLong mnWidth;
@@ -382,14 +377,6 @@ public:
// =======================================================================
-inline void ServerFont::SetExtended( int nInfo, void* pVoid )
-{
- mnExtInfo = nInfo;
- mpExtData = pVoid;
-}
-
-// =======================================================================
-
// ExtraKernInfo allows an on-demand query of extra kerning info #i29881#
// The kerning values have to be scaled to match the font size before use
class VCL_DLLPUBLIC ExtraKernInfo