[Libreoffice-commits] core.git: vcl/generic vcl/headless vcl/inc

Stephan Bergmann sbergman at redhat.com
Fri Jul 12 09:57:17 PDT 2013


 vcl/generic/glyphs/gcach_ftyp.cxx |   21 +++++++----------
 vcl/generic/glyphs/gcach_rbmp.cxx |   25 ++++++++-------------
 vcl/generic/glyphs/glyphcache.cxx |    6 ++---
 vcl/headless/svptext.cxx          |   45 +++++++++++++++++++++-----------------
 vcl/inc/generic/glyphcache.hxx    |   27 +++++-----------------
 5 files changed, 55 insertions(+), 69 deletions(-)

New commits:
commit dd547e4a8c1895aa89e699810323c933d9ac415b
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Fri Jul 12 18:51:26 2013 +0200

    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

diff --git a/vcl/generic/glyphs/gcach_ftyp.cxx b/vcl/generic/glyphs/gcach_ftyp.cxx
index 29c8820..979be11 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 684f886..0efe54c 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 a32b88f..43c628d 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 bbe38f4..ff31603 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 1457dd5..d33aee1 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


More information about the Libreoffice-commits mailing list