[Libreoffice-commits] core.git: include/vcl vcl/CppunitTest_vcl_fontcharmap.mk vcl/generic vcl/headless vcl/inc vcl/Module_vcl.mk vcl/qa vcl/quartz vcl/source vcl/unx vcl/win

Chris Sherlock chris.sherlock79 at gmail.com
Sun Oct 5 17:13:58 PDT 2014


 include/vcl/metric.hxx                  |    8 ++-
 vcl/CppunitTest_vcl_fontcharmap.mk      |   53 ++++++++++++++++++++++
 vcl/Module_vcl.mk                       |    1 
 vcl/generic/fontmanager/fontmanager.cxx |    6 +-
 vcl/generic/glyphs/gcach_ftyp.cxx       |   15 ++++--
 vcl/generic/glyphs/gcach_ftyp.hxx       |    4 -
 vcl/generic/print/genpspgraphics.cxx    |    4 -
 vcl/headless/svptext.cxx                |    4 -
 vcl/inc/generic/genpspgraphics.h        |    2 
 vcl/inc/generic/glyphcache.hxx          |    2 
 vcl/inc/headless/svpgdi.hxx             |    2 
 vcl/inc/impfont.hxx                     |   24 ++++++++-
 vcl/inc/quartz/salgdi.h                 |    6 +-
 vcl/inc/salgdi.hxx                      |    4 -
 vcl/inc/unx/salgdi.h                    |    2 
 vcl/inc/win/salgdi.h                    |    6 +-
 vcl/qa/cppunit/fontcharmap.cxx          |   48 +++++++++++++++++++
 vcl/quartz/salgdi.cxx                   |   23 +++------
 vcl/source/gdi/impfont.cxx              |   77 ++++++++++++--------------------
 vcl/source/outdev/font.cxx              |    2 
 vcl/unx/generic/gdi/salgdi3.cxx         |    4 -
 vcl/win/source/gdi/salgdi3.cxx          |   28 +++++------
 vcl/win/source/gdi/winlayout.cxx        |    2 
 23 files changed, 215 insertions(+), 112 deletions(-)

New commits:
commit 9177329a425cf70b515d1f266132838894fe54c6
Author: Chris Sherlock <chris.sherlock79 at gmail.com>
Date:   Sat Oct 4 21:55:58 2014 +1000

    vcl: FontCharMap to use intrusive_ptr ImplFontCharMap
    
    ImplFontCharMap was using it's own reference counting mechanism,
    however we can use intrusive_ptr more effectively.
    
    Added a unit test around FontCharMap.
    
    Change-Id: Ifab6ce002fd1df8feb7e017dea3012ff9ea7f18a
    Reviewed-on: https://gerrit.libreoffice.org/11804
    Reviewed-by: Chris Sherlock <chris.sherlock79 at gmail.com>
    Tested-by: Chris Sherlock <chris.sherlock79 at gmail.com>

diff --git a/include/vcl/metric.hxx b/include/vcl/metric.hxx
index c22c553..0bc977a 100644
--- a/include/vcl/metric.hxx
+++ b/include/vcl/metric.hxx
@@ -24,10 +24,13 @@
 #include <vcl/font.hxx>
 #include <vcl/outdev.hxx>
 
+#include <boost/intrusive_ptr.hpp>
+
 class ImplFontMetric;
 class ImplFontCharMap;
 
 typedef sal_uInt32 sal_UCS4;
+typedef boost::intrusive_ptr< ImplFontCharMap > ImplFontCharMapPtr;
 
 namespace vcl {
 
@@ -94,7 +97,7 @@ inline std::basic_ostream<charT, traits> & operator <<(
 class VCL_DLLPUBLIC FontCharMap
 {
 private:
-    const ImplFontCharMap* mpImpl;
+    ImplFontCharMapPtr  mpImplFontCharMap;
 
 public:
                         FontCharMap();
@@ -106,6 +109,7 @@ public:
     int                 GetCharCount( void ) const;
 
     sal_UCS4            GetFirstChar() const;
+    sal_UCS4            GetLastChar() const;
 
     sal_UCS4            GetNextChar( sal_UCS4 ) const;
     sal_UCS4            GetPrevChar( sal_UCS4 ) const;
@@ -116,7 +120,7 @@ public:
 
 private:
     friend class ::OutputDevice;
-    void                Reset( const ImplFontCharMap* pNewMap = NULL );
+    void                Reset( const ImplFontCharMapPtr pNewMap = NULL );
 
     // prevent assignment and copy construction
                         FontCharMap( const FontCharMap& );
diff --git a/vcl/CppunitTest_vcl_fontcharmap.mk b/vcl/CppunitTest_vcl_fontcharmap.mk
new file mode 100644
index 0000000..0a89f41
--- /dev/null
+++ b/vcl/CppunitTest_vcl_fontcharmap.mk
@@ -0,0 +1,53 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,vcl_fontcharmap))
+
+$(eval $(call gb_CppunitTest_set_include,vcl_fontcharmap,\
+    $$(INCLUDE) \
+    -I$(SRCDIR)/vcl/inc \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,vcl_fontcharmap, \
+	vcl/qa/cppunit/fontcharmap \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,vcl_fontcharmap,boost_headers))
+
+$(eval $(call gb_CppunitTest_use_libraries,vcl_fontcharmap, \
+	comphelper \
+	cppu \
+	cppuhelper \
+	sal \
+	svt \
+	test \
+	tl \
+	tk \
+	unotest \
+	vcl \
+	$(gb_UWINAPI) \
+))
+
+$(eval $(call gb_CppunitTest_use_api,vcl_fontcharmap,\
+	udkapi \
+	offapi \
+))
+
+$(eval $(call gb_CppunitTest_use_ure,vcl_fontcharmap))
+$(eval $(call gb_CppunitTest_use_vcl,vcl_fontcharmap))
+
+$(eval $(call gb_CppunitTest_use_components,vcl_fontcharmap,\
+	configmgr/source/configmgr \
+	i18npool/util/i18npool \
+	ucb/source/core/ucb1 \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,vcl_fontcharmap))
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index f2eef6f..d875016 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -94,6 +94,7 @@ $(eval $(call gb_Module_add_targets,vcl,\
 endif
 
 $(eval $(call gb_Module_add_check_targets,vcl,\
+	CppunitTest_vcl_fontcharmap \
 	CppunitTest_vcl_complextext \
 	CppunitTest_vcl_filters_test \
 	CppunitTest_vcl_app_test \
diff --git a/vcl/generic/fontmanager/fontmanager.cxx b/vcl/generic/fontmanager/fontmanager.cxx
index 2737076..05fc829 100644
--- a/vcl/generic/fontmanager/fontmanager.cxx
+++ b/vcl/generic/fontmanager/fontmanager.cxx
@@ -2088,11 +2088,11 @@ void PrintFontManager::getGlyphWidths( fontID nFont,
                 CmapResult aCmapResult;
                 if( ParseCMAP( pCmapData, nCmapSize, aCmapResult ) )
                 {
-                    const ImplFontCharMap aCharMap( aCmapResult );
+                    const ImplFontCharMapPtr pCharMap( new ImplFontCharMap(aCmapResult) );
                     for( sal_uInt32 cOld = 0;;)
                     {
                         // get next unicode covered by font
-                        const sal_uInt32 c = aCharMap.GetNextChar( cOld );
+                        const sal_uInt32 c = pCharMap->GetNextChar( cOld );
                         if( c == cOld )
                             break;
                         cOld = c;
@@ -2101,7 +2101,7 @@ void PrintFontManager::getGlyphWidths( fontID nFont,
                             break;
 #endif
                         // get the matching glyph index
-                        const sal_GlyphId aGlyphId = aCharMap.GetGlyphIndex( c );
+                        const sal_GlyphId aGlyphId = pCharMap->GetGlyphIndex( c );
                         // update the requested map
                         rUnicodeEnc[ (sal_Unicode)c ] = aGlyphId;
                     }
diff --git a/vcl/generic/glyphs/gcach_ftyp.cxx b/vcl/generic/glyphs/gcach_ftyp.cxx
index 9db574e..fa93fc6 100644
--- a/vcl/generic/glyphs/gcach_ftyp.cxx
+++ b/vcl/generic/glyphs/gcach_ftyp.cxx
@@ -242,7 +242,7 @@ FtFontInfo::FtFontInfo( const ImplDevFontAttributes& rDevFontAttributes,
 FtFontInfo::~FtFontInfo()
 {
     if( mpFontCharMap )
-        mpFontCharMap->DeReference();
+        mpFontCharMap = 0;
     delete mpChar2Glyph;
     delete mpGlyph2Char;
 #if ENABLE_GRAPHITE
@@ -1265,13 +1265,13 @@ bool ServerFont::GetGlyphBitmap8( sal_GlyphId aGlyphId, RawBitmap& rRawBitmap )
 
 // determine unicode ranges in font
 
-const ImplFontCharMap* ServerFont::GetImplFontCharMap( void ) const
+const ImplFontCharMapPtr ServerFont::GetImplFontCharMap( void ) const
 {
-    const ImplFontCharMap* pIFCMap = mpFontInfo->GetImplFontCharMap();
+    const ImplFontCharMapPtr pIFCMap = mpFontInfo->GetImplFontCharMap();
     return pIFCMap;
 }
 
-const ImplFontCharMap* FtFontInfo::GetImplFontCharMap( void )
+const ImplFontCharMapPtr FtFontInfo::GetImplFontCharMap( void )
 {
     // check if the charmap is already cached
     if( mpFontCharMap )
@@ -1281,9 +1281,14 @@ const ImplFontCharMap* FtFontInfo::GetImplFontCharMap( void )
     CmapResult aCmapResult;
     bool bOK = GetFontCodeRanges( aCmapResult );
     if( bOK )
-        mpFontCharMap = new ImplFontCharMap( aCmapResult );
+    {
+        ImplFontCharMapPtr pFontCharMap( new ImplFontCharMap( aCmapResult ) );
+        mpFontCharMap = pFontCharMap;
+    }
     else
+    {
         mpFontCharMap = ImplFontCharMap::GetDefaultMap();
+    }
     // mpFontCharMap on either branch now has a refcount of 1
     return mpFontCharMap;
 }
diff --git a/vcl/generic/glyphs/gcach_ftyp.hxx b/vcl/generic/glyphs/gcach_ftyp.hxx
index b43d47b..803ce07 100644
--- a/vcl/generic/glyphs/gcach_ftyp.hxx
+++ b/vcl/generic/glyphs/gcach_ftyp.hxx
@@ -84,7 +84,7 @@ public:
     void                  CacheGlyphIndex( sal_UCS4 cChar, int nGI ) const;
 
     bool                  GetFontCodeRanges( CmapResult& ) const;
-    const ImplFontCharMap* GetImplFontCharMap( void );
+    const ImplFontCharMapPtr GetImplFontCharMap( void );
 
 private:
     FT_FaceRec_*    maFaceFT;
@@ -99,7 +99,7 @@ private:
     sal_IntPtr      mnFontId;
     ImplDevFontAttributes maDevFontAttributes;
 
-    const ImplFontCharMap* mpFontCharMap;
+    ImplFontCharMapPtr mpFontCharMap;
 
     // cache unicode->glyphid mapping because looking it up is expensive
     // TODO: change to boost::unordered_multimap when a use case requires a m:n mapping
diff --git a/vcl/generic/print/genpspgraphics.cxx b/vcl/generic/print/genpspgraphics.cxx
index 401f5c7..759519b 100644
--- a/vcl/generic/print/genpspgraphics.cxx
+++ b/vcl/generic/print/genpspgraphics.cxx
@@ -777,12 +777,12 @@ void GenPspGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
     DrawPrinterLayout( rLayout, *m_pPrinterGfx, true );
 }
 
-const ImplFontCharMap* GenPspGraphics::GetImplFontCharMap() const
+const ImplFontCharMapPtr GenPspGraphics::GetImplFontCharMap() const
 {
     if( !m_pServerFont[0] )
         return NULL;
 
-    const ImplFontCharMap* pIFCMap = m_pServerFont[0]->GetImplFontCharMap();
+    const ImplFontCharMapPtr pIFCMap = m_pServerFont[0]->GetImplFontCharMap();
     return pIFCMap;
 }
 
diff --git a/vcl/headless/svptext.cxx b/vcl/headless/svptext.cxx
index 3f2384c..905d78b 100644
--- a/vcl/headless/svptext.cxx
+++ b/vcl/headless/svptext.cxx
@@ -231,12 +231,12 @@ void SvpSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLe
     }
 }
 
-const ImplFontCharMap* SvpSalGraphics::GetImplFontCharMap() const
+const ImplFontCharMapPtr SvpSalGraphics::GetImplFontCharMap() const
 {
     if( !m_pServerFont[0] )
         return NULL;
 
-    const ImplFontCharMap* pIFCMap = m_pServerFont[0]->GetImplFontCharMap();
+    const ImplFontCharMapPtr pIFCMap = m_pServerFont[0]->GetImplFontCharMap();
     return pIFCMap;
 }
 
diff --git a/vcl/inc/generic/genpspgraphics.h b/vcl/inc/generic/genpspgraphics.h
index ec54d5b..66c7f31 100644
--- a/vcl/inc/generic/genpspgraphics.h
+++ b/vcl/inc/generic/genpspgraphics.h
@@ -89,7 +89,7 @@ public:
     virtual void            SetTextColor( SalColor nSalColor ) SAL_OVERRIDE;
     virtual sal_uInt16      SetFont( FontSelectPattern*, int nFallbackLevel ) SAL_OVERRIDE;
     virtual void            GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) SAL_OVERRIDE;
-    virtual const ImplFontCharMap* GetImplFontCharMap() const SAL_OVERRIDE;
+    virtual const ImplFontCharMapPtr GetImplFontCharMap() const SAL_OVERRIDE;
     virtual bool            GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const SAL_OVERRIDE;
     virtual void            GetDevFontList( PhysicalFontCollection* ) SAL_OVERRIDE;
     // graphics must drop any cached font info
diff --git a/vcl/inc/generic/glyphcache.hxx b/vcl/inc/generic/glyphcache.hxx
index a3b1c4f..40a07da 100644
--- a/vcl/inc/generic/glyphcache.hxx
+++ b/vcl/inc/generic/glyphcache.hxx
@@ -182,7 +182,7 @@ public:
     const unsigned char* GetTable( const char* pName, sal_uLong* pLength );
     int                 GetEmUnits() const { return maFaceFT->units_per_EM;}
     const FT_Size_Metrics& GetMetricsFT() const { return maSizeFT->metrics; }
-    const ImplFontCharMap* GetImplFontCharMap() const;
+    const ImplFontCharMapPtr GetImplFontCharMap() const;
     bool                GetFontCapabilities(vcl::FontCapabilities &) const;
 
     GlyphData&                  GetGlyphData( sal_GlyphId );
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
index 65a8fc2..aad4693 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -156,7 +156,7 @@ public:
     virtual void            SetTextColor( SalColor nSalColor ) SAL_OVERRIDE;
     virtual sal_uInt16      SetFont( FontSelectPattern*, int nFallbackLevel ) SAL_OVERRIDE;
     virtual void            GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) SAL_OVERRIDE;
-    virtual const ImplFontCharMap* GetImplFontCharMap() const SAL_OVERRIDE;
+    virtual const ImplFontCharMapPtr GetImplFontCharMap() const SAL_OVERRIDE;
     virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const SAL_OVERRIDE;
     virtual void            GetDevFontList( PhysicalFontCollection* ) SAL_OVERRIDE;
     virtual void ClearDevFontCache() SAL_OVERRIDE;
diff --git a/vcl/inc/impfont.hxx b/vcl/inc/impfont.hxx
index 3c42f6e..af97677 100644
--- a/vcl/inc/impfont.hxx
+++ b/vcl/inc/impfont.hxx
@@ -29,6 +29,11 @@
 #include <vcl/fntstyle.hxx>
 #include <outfont.hxx>
 
+#include <boost/intrusive_ptr.hpp>
+
+class ImplFontCharMap;
+typedef boost::intrusive_ptr< ImplFontCharMap > ImplFontCharMapPtr;
+
 // - Impl_Font -
 
 class Impl_Font
@@ -158,7 +163,7 @@ public:
     explicit            ImplFontCharMap( const CmapResult& );
     virtual             ~ImplFontCharMap();
 
-    static ImplFontCharMap* GetDefaultMap( bool bSymbols=false);
+    static ImplFontCharMapPtr GetDefaultMap( bool bSymbols=false);
 
     bool                IsDefaultMap() const;
     bool                HasChar( sal_uInt32 ) const;
@@ -174,12 +179,12 @@ public:
     int                 GetIndexFromChar( sal_uInt32 ) const;
     sal_uInt32          GetCharFromIndex( int ) const;
 
-    void                AddReference() const;
-    void                DeReference() const;
-
     int                 GetGlyphIndex( sal_uInt32 ) const;
 
 private:
+    friend void intrusive_ptr_add_ref(ImplFontCharMap* pImplFontCharMap);
+    friend void intrusive_ptr_release(ImplFontCharMap* pImplFontCharMap);
+
     int                 ImplFindRangeIndex( sal_uInt32 ) const;
 
     // prevent assignment and copy construction
@@ -195,6 +200,17 @@ private:
     mutable sal_uInt32  mnRefCount;
 };
 
+inline void intrusive_ptr_add_ref(ImplFontCharMap* pImplFontCharMap)
+{
+    ++pImplFontCharMap->mnRefCount;
+}
+
+inline void intrusive_ptr_release(ImplFontCharMap* pImplFontCharMap)
+{
+    if (--pImplFontCharMap->mnRefCount == 0)
+        delete pImplFontCharMap;
+}
+
 // CmapResult is a normalized version of the many CMAP formats
 class VCL_PLUGIN_PUBLIC CmapResult
 {
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 8aad534..0c58ca7 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -73,7 +73,7 @@ public:
     CoreTextStyle*                  CreateTextStyle( const FontSelectPattern& ) const;
     int                             GetFontTable( const char pTagName[5], unsigned char* ) const;
 
-    const ImplFontCharMap*          GetImplFontCharMap() const;
+    const ImplFontCharMapPtr        GetImplFontCharMap() const;
     bool                            GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const;
     bool                            HasChar( sal_uInt32 cChar ) const;
 
@@ -85,7 +85,7 @@ protected:
 
 private:
     const sal_IntPtr                mnFontId;
-    mutable const ImplFontCharMap*  mpCharMap;
+    mutable ImplFontCharMapPtr      mpCharMap;
     mutable vcl::FontCapabilities   maFontCapabilities;
     mutable bool                    mbOs2Read;       // true if OS2-table related info is valid
     mutable bool                    mbHasOs2Table;
@@ -330,7 +330,7 @@ public:
     // get the current font's metrics
     virtual void            GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) SAL_OVERRIDE;
     // get the repertoire of the current font
-    virtual const ImplFontCharMap*
+    virtual const ImplFontCharMapPtr
                             GetImplFontCharMap() const SAL_OVERRIDE;
     virtual bool            GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const SAL_OVERRIDE;
     // graphics must fill supplied font list
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index bed8474..c2752b9 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -28,6 +28,7 @@
 #include "vcl/salnativewidgets.hxx"
 #include "salglyphid.hxx"
 #include "sallayout.hxx"
+#include <impfont.hxx>
 
 #include <map>
 
@@ -36,7 +37,6 @@ class SalBitmap;
 class FontSelectPattern;
 class ImplFontMetricData;
 class PhysicalFontFace;
-class ImplFontCharMap;
 class SalLayout;
 class ImplLayoutArgs;
 class Rectangle;
@@ -231,7 +231,7 @@ public:
     virtual void            GetFontMetric( ImplFontMetricData*, int nFallbackLevel = 0 ) = 0;
 
     // get the repertoire of the current font
-    virtual const ImplFontCharMap*
+    virtual const ImplFontCharMapPtr
                             GetImplFontCharMap() const = 0;
 
     // get the layout capabilities of the current font
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 978e514..ba0814b 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -229,7 +229,7 @@ public:
     virtual void            SetTextColor( SalColor nSalColor ) SAL_OVERRIDE;
     virtual sal_uInt16          SetFont( FontSelectPattern*, int nFallbackLevel ) SAL_OVERRIDE;
     virtual void            GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) SAL_OVERRIDE;
-    virtual const ImplFontCharMap* GetImplFontCharMap() const SAL_OVERRIDE;
+    virtual const ImplFontCharMapPtr GetImplFontCharMap() const SAL_OVERRIDE;
     virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const SAL_OVERRIDE;
     virtual void            GetDevFontList( PhysicalFontCollection* ) SAL_OVERRIDE;
     virtual void ClearDevFontCache() SAL_OVERRIDE;
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 957db91..ace973c 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -94,7 +94,7 @@ public:
     const gr_face*          GraphiteFace() const;
 #endif
 
-    const ImplFontCharMap*  GetImplFontCharMap() const;
+    const ImplFontCharMapPtr GetImplFontCharMap() const;
     bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const;
     const Ucs2SIntMap* GetEncodingVector() const { return mpEncodingVector; }
     void SetEncodingVector( const Ucs2SIntMap* pNewVec ) const
@@ -116,7 +116,7 @@ private:
 #endif
     mutable bool                    mbHasArabicSupport;
     mutable bool                    mbFontCapabilitiesRead;
-    mutable ImplFontCharMap*        mpUnicodeMap;
+    mutable ImplFontCharMapPtr      mpUnicodeMap;
     mutable const Ucs2SIntMap*      mpEncodingVector;
     mutable vcl::FontCapabilities   maFontCapabilities;
 
@@ -310,7 +310,7 @@ public:
     // get the current font's metrics
     virtual void            GetFontMetric( ImplFontMetricData*, int nFallbackLevel );
     // get the repertoire of the current font
-    virtual const ImplFontCharMap* GetImplFontCharMap() const;
+    virtual const ImplFontCharMapPtr GetImplFontCharMap() const;
     // get the layout capabilities of the current font
     virtual bool GetFontCapabilities(vcl::FontCapabilities &rGetFontCapabilities) const;
     // graphics must fill supplied font list
diff --git a/vcl/qa/cppunit/fontcharmap.cxx b/vcl/qa/cppunit/fontcharmap.cxx
new file mode 100644
index 0000000..1fee918
--- /dev/null
+++ b/vcl/qa/cppunit/fontcharmap.cxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+
+#include <osl/file.hxx>
+#include <osl/process.h>
+
+#include <vcl/metric.hxx>
+
+class VclFontCharMapTest : public test::BootstrapFixture
+{
+public:
+    VclFontCharMapTest() : BootstrapFixture(true, false) {}
+
+    void testDefaultFontCharMap();
+
+    CPPUNIT_TEST_SUITE(VclFontCharMapTest);
+    CPPUNIT_TEST(testDefaultFontCharMap);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+void VclFontCharMapTest::testDefaultFontCharMap()
+{
+    FontCharMap *fcmap = new FontCharMap(); // gets default map
+
+    CPPUNIT_ASSERT( fcmap->IsDefaultMap() );
+
+    sal_uInt32 nStartBMPPlane = fcmap->GetFirstChar();
+    sal_uInt32 nStartSupBMPPlane = fcmap->GetNextChar(0xD800);
+    sal_uInt32 nEndBMPPlane = fcmap->GetLastChar();
+
+    CPPUNIT_ASSERT( nStartBMPPlane == 0x0020 );
+    CPPUNIT_ASSERT( nStartSupBMPPlane == 0xE000 );
+    CPPUNIT_ASSERT( nEndBMPPlane == 0xFFF0-1 );
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(VclFontCharMapTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index 80d6d5e..b5f5251 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -62,19 +62,17 @@ using namespace vcl;
 CoreTextFontData::CoreTextFontData( const CoreTextFontData& rSrc )
 :   PhysicalFontFace( rSrc )
 ,   mnFontId( rSrc.mnFontId )
-,   mpCharMap( rSrc.mpCharMap )
 ,   mbOs2Read( rSrc.mbOs2Read )
 ,   mbHasOs2Table( rSrc.mbHasOs2Table )
 ,   mbCmapEncodingRead( rSrc.mbCmapEncodingRead )
 {
-    if( mpCharMap )
-        mpCharMap->AddReference();
+    if( rSrc.mpCharMap )
+        mpCharMap = rSrc.mpCharMap;
 }
 
 CoreTextFontData::CoreTextFontData( const ImplDevFontAttributes& rDFA, sal_IntPtr nFontId )
 :   PhysicalFontFace( rDFA, 0 )
 ,   mnFontId( nFontId )
-,   mpCharMap( NULL )
 ,   mbOs2Read( false )
 ,   mbHasOs2Table( false )
 ,   mbCmapEncodingRead( false )
@@ -85,7 +83,7 @@ CoreTextFontData::CoreTextFontData( const ImplDevFontAttributes& rDFA, sal_IntPt
 CoreTextFontData::~CoreTextFontData()
 {
     if( mpCharMap )
-        mpCharMap->DeReference();
+        mpCharMap = 0;
 }
 
 sal_IntPtr CoreTextFontData::GetFontId() const
@@ -95,7 +93,7 @@ sal_IntPtr CoreTextFontData::GetFontId() const
 
 static unsigned GetUShort( const unsigned char* p ){return((p[0]<<8)+p[1]);}
 
-const ImplFontCharMap* CoreTextFontData::GetImplFontCharMap() const
+const ImplFontCharMapPtr CoreTextFontData::GetImplFontCharMap() const
 {
     // return the cached charmap
     if( mpCharMap )
@@ -103,7 +101,6 @@ const ImplFontCharMap* CoreTextFontData::GetImplFontCharMap() const
 
     // set the default charmap
     mpCharMap = ImplFontCharMap::GetDefaultMap();
-    mpCharMap->AddReference();
 
     // get the CMAP byte size
     // allocate a buffer for the CMAP raw data
@@ -124,10 +121,9 @@ const ImplFontCharMap* CoreTextFontData::GetImplFontCharMap() const
     CmapResult aCmapResult;
     if( ParseCMAP( &aBuffer[0], nRawLength, aCmapResult ) )
     {
+        ImplFontCharMapPtr pCharMap(new ImplFontCharMap( aCmapResult ) );
         // create the matching charmap
-        mpCharMap->DeReference();
-        mpCharMap = new ImplFontCharMap( aCmapResult );
-        mpCharMap->AddReference();
+        mpCharMap = pCharMap;
     }
 
     return mpCharMap;
@@ -489,7 +485,7 @@ SalLayout* AquaSalGraphics::GetTextLayout( ImplLayoutArgs& /*rArgs*/, int /*nFal
     return pSalLayout;
 }
 
-const ImplFontCharMap* AquaSalGraphics::GetImplFontCharMap() const
+const ImplFontCharMapPtr AquaSalGraphics::GetImplFontCharMap() const
 {
     if( !mpFontData )
         return ImplFontCharMap::GetDefaultMap();
@@ -726,9 +722,8 @@ void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFontData, bool bV
                 free( (void*)pGlyphMetrics );
             }
 
-            const ImplFontCharMap* pMap = mpFontData->GetImplFontCharMap();
+            ImplFontCharMapPtr pMap = mpFontData->GetImplFontCharMap();
             DBG_ASSERT( pMap && pMap->GetCharCount(), "no charmap" );
-            pMap->AddReference(); // TODO: add and use RAII object instead
 
             // get unicode<->glyph encoding
             // TODO? avoid sft mapping by using the pMap itself
@@ -744,7 +739,7 @@ void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFontData, bool bV
                     rUnicodeEnc[ nUcsChar ] = nGlyph;
             }
 
-            pMap->DeReference(); // TODO: add and use RAII object instead
+            pMap = 0;
         }
 
         ::CloseTTFont( pSftFont );
diff --git a/vcl/source/gdi/impfont.cxx b/vcl/source/gdi/impfont.cxx
index d0d285b..e4e6fc8 100644
--- a/vcl/source/gdi/impfont.cxx
+++ b/vcl/source/gdi/impfont.cxx
@@ -50,7 +50,7 @@ ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR )
     }
 }
 
-static ImplFontCharMap* pDefaultImplFontCharMap = NULL;
+static ImplFontCharMapPtr pDefaultImplFontCharMap;
 static const sal_UCS4 aDefaultUnicodeRanges[] = {0x0020,0xD800, 0xE000,0xFFF0};
 static const sal_UCS4 aDefaultSymbolRanges[] = {0x0020,0x0100, 0xF020,0xF100};
 
@@ -69,40 +69,22 @@ ImplFontCharMap::~ImplFontCharMap()
     delete[] mpGlyphIds;
 }
 
-ImplFontCharMap* ImplFontCharMap::GetDefaultMap( bool bSymbols)
+ImplFontCharMapPtr ImplFontCharMap::GetDefaultMap( bool bSymbols)
 {
-    if( pDefaultImplFontCharMap )
-        pDefaultImplFontCharMap->AddReference();
-    else
+    const sal_UCS4* pRangeCodes = aDefaultUnicodeRanges;
+    int nCodesCount = sizeof(aDefaultUnicodeRanges) / sizeof(*pRangeCodes);
+    if( bSymbols )
     {
-        const sal_UCS4* pRangeCodes = aDefaultUnicodeRanges;
-        int nCodesCount = sizeof(aDefaultUnicodeRanges) / sizeof(*pRangeCodes);
-        if( bSymbols )
-        {
-            pRangeCodes = aDefaultSymbolRanges;
-            nCodesCount = sizeof(aDefaultSymbolRanges) / sizeof(*pRangeCodes);
-        }
-
-        CmapResult aDefaultCR( bSymbols, pRangeCodes, nCodesCount/2 );
-        pDefaultImplFontCharMap = new ImplFontCharMap( aDefaultCR );
+        pRangeCodes = aDefaultSymbolRanges;
+        nCodesCount = sizeof(aDefaultSymbolRanges) / sizeof(*pRangeCodes);
     }
 
-    return pDefaultImplFontCharMap;
-}
+    CmapResult aDefaultCR( bSymbols, pRangeCodes, nCodesCount/2 );
+    pDefaultImplFontCharMap.reset( new ImplFontCharMap( aDefaultCR ) );
 
-void ImplFontCharMap::AddReference( void) const
-{
-    ++mnRefCount;
-}
-
-void ImplFontCharMap::DeReference( void) const
-{
-    if( --mnRefCount <= 0 )
-        if( this != pDefaultImplFontCharMap )
-            delete this;
+    return pDefaultImplFontCharMap;
 }
 
-
 int ImplFontCharMap::ImplFindRangeIndex( sal_UCS4 cChar ) const
 {
     int nLower = 0;
@@ -561,73 +543,74 @@ bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
 }
 
 FontCharMap::FontCharMap()
-:   mpImpl( ImplFontCharMap::GetDefaultMap() )
+:   mpImplFontCharMap( ImplFontCharMap::GetDefaultMap() )
 {}
 
 FontCharMap::~FontCharMap()
 {
-    mpImpl->DeReference();
-    mpImpl = NULL;
+    mpImplFontCharMap = 0;
 }
 
 int FontCharMap::GetCharCount() const
 {
-    return mpImpl->GetCharCount();
+    return mpImplFontCharMap->GetCharCount();
 }
 
 int FontCharMap::CountCharsInRange( sal_UCS4 cMin, sal_UCS4 cMax ) const
 {
-    return mpImpl->CountCharsInRange( cMin, cMax );
+    return mpImplFontCharMap->CountCharsInRange( cMin, cMax );
 }
 
-void FontCharMap::Reset( const ImplFontCharMap* pNewMap )
+void FontCharMap::Reset( const ImplFontCharMapPtr pNewMap )
 {
     if( pNewMap == NULL )
     {
-        mpImpl->DeReference();
-        mpImpl = ImplFontCharMap::GetDefaultMap();
+        mpImplFontCharMap = ImplFontCharMap::GetDefaultMap();
     }
-    else if( pNewMap != mpImpl )
+    else if( pNewMap != mpImplFontCharMap )
     {
-        mpImpl->DeReference();
-        mpImpl = pNewMap;
-        mpImpl->AddReference();
+        mpImplFontCharMap = pNewMap;
     }
 }
 
 bool FontCharMap::IsDefaultMap() const
 {
-    return mpImpl->IsDefaultMap();
+    return mpImplFontCharMap->IsDefaultMap();
 }
 
 bool FontCharMap::HasChar( sal_UCS4 cChar ) const
 {
-    return mpImpl->HasChar( cChar );
+    return mpImplFontCharMap->HasChar( cChar );
 }
 
 sal_UCS4 FontCharMap::GetFirstChar() const
 {
-    return mpImpl->GetFirstChar();
+    return mpImplFontCharMap->GetFirstChar();
+}
+
+sal_UCS4 FontCharMap::GetLastChar() const
+{
+    return mpImplFontCharMap->GetLastChar();
 }
 
 sal_UCS4 FontCharMap::GetNextChar( sal_UCS4 cChar ) const
 {
-    return mpImpl->GetNextChar( cChar );
+    return mpImplFontCharMap->GetNextChar( cChar );
 }
 
 sal_UCS4 FontCharMap::GetPrevChar( sal_UCS4 cChar ) const
 {
-    return mpImpl->GetPrevChar( cChar );
+    return mpImplFontCharMap->GetPrevChar( cChar );
 }
 
 int FontCharMap::GetIndexFromChar( sal_UCS4 cChar ) const
 {
-    return mpImpl->GetIndexFromChar( cChar );
+    return mpImplFontCharMap->GetIndexFromChar( cChar );
 }
 
 sal_UCS4 FontCharMap::GetCharFromIndex( int nIndex ) const
 {
-    return mpImpl->GetCharFromIndex( nIndex );
+    return mpImplFontCharMap->GetCharFromIndex( nIndex );
 }
 
 // on some systems we have to get the font attributes from the name table
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index 7b83d04..0a7733d 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -231,7 +231,7 @@ bool OutputDevice::GetFontCharMap( FontCharMap& rFontCharMap ) const
     if( !mpFontEntry )
         return false;
 
-    const ImplFontCharMap* pNewMap = mpGraphics->GetImplFontCharMap();
+    const ImplFontCharMapPtr pNewMap = mpGraphics->GetImplFontCharMap();
     rFontCharMap.Reset( pNewMap );
 
     if( rFontCharMap.IsDefaultMap() )
diff --git a/vcl/unx/generic/gdi/salgdi3.cxx b/vcl/unx/generic/gdi/salgdi3.cxx
index 13d550e..f028597 100644
--- a/vcl/unx/generic/gdi/salgdi3.cxx
+++ b/vcl/unx/generic/gdi/salgdi3.cxx
@@ -431,12 +431,12 @@ void X11SalGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
     cairo_destroy(cr);
 }
 
-const ImplFontCharMap* X11SalGraphics::GetImplFontCharMap() const
+const ImplFontCharMapPtr X11SalGraphics::GetImplFontCharMap() const
 {
     if( !mpServerFont[0] )
         return NULL;
 
-    const ImplFontCharMap* pIFCMap = mpServerFont[0]->GetImplFontCharMap();
+    const ImplFontCharMapPtr pIFCMap = mpServerFont[0]->GetImplFontCharMap();
     return pIFCMap;
 }
 
diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx
index efa5417..cb5be79 100644
--- a/vcl/win/source/gdi/salgdi3.cxx
+++ b/vcl/win/source/gdi/salgdi3.cxx
@@ -444,7 +444,7 @@ void ImplGetLogFontFromFontSelect( HDC, const FontSelectPattern*,
 bool WinGlyphFallbackSubstititution::HasMissingChars( const PhysicalFontFace* pFace, const OUString& rMissingChars ) const
 {
     const ImplWinFontData* pWinFont = static_cast<const ImplWinFontData*>(pFace);
-    const ImplFontCharMap* pCharMap = pWinFont->GetImplFontCharMap();
+    ImplFontCharMapPtr pCharMap = pWinFont->GetImplFontCharMap();
     if( !pCharMap )
     {
         // construct a Size structure as the parameter of constructor of class FontSelectPattern
@@ -474,7 +474,6 @@ bool WinGlyphFallbackSubstititution::HasMissingChars( const PhysicalFontFace* pF
     // avoid fonts with unknown CMAP subtables for glyph fallback
     if( !pCharMap || pCharMap->IsDefaultMap() )
         return false;
-        pCharMap->AddReference();
 
     int nMatchCount = 0;
     // static const int nMaxMatchCount = 1; // TODO: tolerate more missing characters?
@@ -485,7 +484,8 @@ bool WinGlyphFallbackSubstititution::HasMissingChars( const PhysicalFontFace* pF
         nMatchCount += pCharMap->HasChar( uChar );
         break; // for now
     }
-        pCharMap->DeReference();
+
+    pCharMap = 0;
 
     const bool bHasMatches = (nMatchCount > 0);
     return bHasMatches;
@@ -1137,7 +1137,7 @@ ImplWinFontData::~ImplWinFontData()
     delete[] mpFontCharSets;
 
     if( mpUnicodeMap )
-        mpUnicodeMap->DeReference();
+        mpUnicodeMap = 0;
 #if ENABLE_GRAPHITE
     if (mpGraphiteData)
         mpGraphiteData->DeReference();
@@ -1224,7 +1224,7 @@ bool ImplWinFontData::IsGSUBstituted( sal_UCS4 cChar ) const
     return( maGsubTable.find( cChar ) != maGsubTable.end() );
 }
 
-const ImplFontCharMap* ImplWinFontData::GetImplFontCharMap() const
+const ImplFontCharMapPtr ImplWinFontData::GetImplFontCharMap() const
 {
     if( !mpUnicodeMap )
         return NULL;
@@ -1298,12 +1298,14 @@ void ImplWinFontData::ReadCmapTable( HDC hDC ) const
         mbDisableGlyphApi |= aResult.mbRecoded;
         aResult.mbSymbolic = bIsSymbolFont;
         if( aResult.mnRangeCount > 0 )
-            mpUnicodeMap = new ImplFontCharMap( aResult );
+        {
+            ImplFontCharMapPtr pUnicodeMap( new ImplFontCharMap( aResult ) );
+            mpUnicodeMap = pUnicodeMap;
+        }
     }
 
     if( !mpUnicodeMap )
         mpUnicodeMap = ImplFontCharMap::GetDefaultMap( bIsSymbolFont );
-    mpUnicodeMap->AddReference();
 }
 
 void ImplWinFontData::GetFontCapabilities( HDC hDC ) const
@@ -1697,7 +1699,7 @@ sal_uLong WinSalGraphics::GetKernPairs()
     return mnFontKernPairCount;
 }
 
-const ImplFontCharMap* WinSalGraphics::GetImplFontCharMap() const
+const ImplFontCharMapPtr WinSalGraphics::GetImplFontCharMap() const
 {
     if( !mpWinFontData[0] )
         return ImplFontCharMap::GetDefaultMap();
@@ -2480,8 +2482,7 @@ bool WinSalGraphics::CreateFontSubset( const OUString& rToFile,
     if( aRawCffData.get() )
     {
         pWinFontData->UpdateFromHDC( getHDC() );
-        const ImplFontCharMap* pCharMap = pWinFontData->GetImplFontCharMap();
-        pCharMap->AddReference();
+        ImplFontCharMapPtr pCharMap = pWinFontData->GetImplFontCharMap();
 
         sal_GlyphId aRealGlyphIds[ 256 ];
         for( int i = 0; i < nGlyphCount; ++i )
@@ -2497,7 +2498,7 @@ bool WinSalGraphics::CreateFontSubset( const OUString& rToFile,
             aRealGlyphIds[i] = aGlyphId;
         }
 
-        pCharMap->DeReference(); // TODO: and and use a RAII object
+        pCharMap = 0;
 
         // provide a font subset from the CFF-table
         FILE* pOutFile = fopen( aToFile.getStr(), "wb" );
@@ -2731,9 +2732,8 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
                 rUnicodeEnc.clear();
             }
             const ImplWinFontData* pWinFont = static_cast<const ImplWinFontData*>(pFont);
-            const ImplFontCharMap* pMap = pWinFont->GetImplFontCharMap();
+            ImplFontCharMapPtr pMap = pWinFont->GetImplFontCharMap();
             DBG_ASSERT( pMap && pMap->GetCharCount(), "no map" );
-            pMap->AddReference();
 
             int nCharCount = pMap->GetCharCount();
             sal_uInt32 nChar = pMap->GetFirstChar();
@@ -2750,7 +2750,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
                 nChar = pMap->GetNextChar( nChar );
             }
 
-            pMap->DeReference(); // TODO: and and use a RAII object
+            pMap = 0;
         }
     }
     else if( pFont->IsEmbeddable() )
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index eff3f9c..958348f 100644
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -2952,8 +2952,6 @@ bool ImplWinFontEntry::InitKashidaHandling( HDC hDC )
 
 PhysicalFontFace* ImplWinFontData::Clone() const
 {
-    if( mpUnicodeMap )
-        mpUnicodeMap->AddReference();
 #if ENABLE_GRAPHITE
     if ( mpGraphiteData )
         mpGraphiteData->AddReference();


More information about the Libreoffice-commits mailing list