[Libreoffice-commits] core.git: Branch 'libreoffice-6-4' - vcl/inc vcl/unx

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Tue Nov 19 11:48:08 UTC 2019


 vcl/inc/unx/freetype_glyphcache.hxx            |   14 ++++----
 vcl/inc/unx/glyphcache.hxx                     |   43 +++++++++++++++++++++----
 vcl/unx/generic/app/gendata.cxx                |    1 
 vcl/unx/generic/glyphs/freetype_glyphcache.cxx |   28 +---------------
 vcl/unx/generic/glyphs/glyphcache.cxx          |   15 ++++++++
 5 files changed, 62 insertions(+), 39 deletions(-)

New commits:
commit aac19da146d19033964d7c6ed608cfc4786f88c5
Author:     Jan-Marek Glogowski <jan-marek.glogowski at extern.cib.de>
AuthorDate: Fri Nov 15 16:19:31 2019 +0000
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Tue Nov 19 12:47:26 2019 +0100

    Move static aFontFileList into GlyphCache
    
    GlyphCache is already a global in the unix SalData class, so we
    can drop one more global static variable. and the FontFile map
    values aren't shared, so just use std::unique_ptr, like the two
    other maps, which form the GlyphCache class.
    
    While at it finalize the classes and hide their constructors.
    
    Change-Id: Iaac8cd9905e9b4025707a17f62d8961ccfa5d0fb
    Reviewed-on: https://gerrit.libreoffice.org/82966
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
    (cherry picked from commit 578f97b4b2d06d3d5d5db7fd70066ba8ca665abc)
    Reviewed-on: https://gerrit.libreoffice.org/83147

diff --git a/vcl/inc/unx/freetype_glyphcache.hxx b/vcl/inc/unx/freetype_glyphcache.hxx
index f000264ac3dd..08604d9b3982 100644
--- a/vcl/inc/unx/freetype_glyphcache.hxx
+++ b/vcl/inc/unx/freetype_glyphcache.hxx
@@ -30,11 +30,9 @@ class CmapResult;
 // FreetypeFontFile has the responsibility that a font file is only mapped once.
 // (#86621#) the old directly ft-managed solution caused it to be mapped
 // in up to nTTC*nSizes*nOrientation*nSynthetic times
-class FreetypeFontFile
+class FreetypeFontFile final
 {
 public:
-    static FreetypeFontFile*      FindFontFile( const OString& rNativeFileName );
-
     bool                    Map();
     void                    Unmap();
 
@@ -44,6 +42,7 @@ public:
     int                     GetLangBoost() const { return mnLangBoost; }
 
 private:
+    friend class GlyphCache;
     explicit                FreetypeFontFile( const OString& rNativeFileName );
 
     const OString    maNativeFileName;
@@ -54,11 +53,9 @@ private:
 };
 
 // FreetypeFontInfo corresponds to an unscaled font face
-class FreetypeFontInfo
+class FreetypeFontInfo final
 {
 public:
-    FreetypeFontInfo(const FontAttributes&, const OString& rNativeFileName,
-                     int nFaceNum, int nFaceVariation, sal_IntPtr nFontId);
     ~FreetypeFontInfo();
 
     const unsigned char*  GetTable( const char*, sal_uLong* pLength) const;
@@ -78,6 +75,10 @@ public:
     const FontCharMapRef& GetFontCharMap();
 
 private:
+    friend class GlyphCache;
+    explicit FreetypeFontInfo(const FontAttributes&, FreetypeFontFile* const pFontFile,
+                              int nFaceNum, int nFaceVariation, sal_IntPtr nFontId);
+
     FT_FaceRec_*    maFaceFT;
     FreetypeFontFile* const mpFontFile;
     const int       mnFaceNum;
@@ -101,7 +102,6 @@ public:
     virtual sal_IntPtr      GetFontId() const override { return mpFreetypeFontInfo->GetFontId(); }
 };
 
-// a class for cache entries for physical font instances that are based on serverfonts
 class FreetypeFontInstance : public LogicalFontInstance
 {
     friend rtl::Reference<LogicalFontInstance> FreetypeFontFace::CreateFontInstance(const FontSelectPattern&) const;
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
index b9398ad57d0f..797890a2a345 100644
--- a/vcl/inc/unx/glyphcache.hxx
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -37,6 +37,7 @@
 #include <unordered_map>
 
 class FreetypeFont;
+class FreetypeFontFile;
 class FreetypeFontInstance;
 class FreetypeFontInfo;
 class FontConfigFontOptions;
@@ -47,11 +48,36 @@ class SvpGcpHelper;
 namespace basegfx { class B2DPolyPolygon; }
 namespace vcl { struct FontCapabilities; }
 
+ /**
+  * The GlyphCache caches various aspects of Freetype fonts
+  *
+  * It mainly consists of three std::unordered_map lists, which hold the items of the cache.
+  *
+  * They form kind of a tree, with FreetypeFontFile as the roots, referenced by multiple FreetypeFontInfo
+  * entries, which are referenced by the FreetypeFont items.
+  *
+  * All of these items have reference counters, but these don't control the items life-cycle, but that of
+  * the managed resources.
+  *
+  * The respective resources are:
+  *   FreetypeFontFile = holds the mmapped font file, as long as it's used by any FreetypeFontInfo.
+  *   FreetypeFontInfo = holds the FT_FaceRec_ object, as long as it's used by any FreetypeFont.
+  *   FreetypeFont     = holds the FT_SizeRec_.
+  *
+  * FreetypeFontInfo therefore is embedded in the Freetype subclass of PhysicalFontFace.
+  * FreetypeFont is embedded in the Freetype subclass of LogicalFontInstance.
+  *
+  * Nowadays there is not really a reason to have seperate files for the classes, as the GlyphCache is
+  * just about handling of Freetype based fonts, not some abstract glyphs.
+  *
+  * One additional note: the byte-size based garbage collection of unused fonts can currently be assumed
+  * to be broken. Since the move of the glyph rect cache into the ImplFontCache, so it can be used by all
+  * platforms, it just takes too long to kick-in, as there is no real accounting left.
+  **/
 class VCL_DLLPUBLIC GlyphCache final
 {
 public:
-    explicit                GlyphCache();
-    virtual                 ~GlyphCache();
+    ~GlyphCache();
 
     static GlyphCache&      GetInstance();
 
@@ -68,9 +94,14 @@ public:
     void                    ClearFontOptions();
 
 private:
+    // to access the constructor (can't use InitFreetypeManager function, because it's private?!)
+    friend class GenericUnixSalData;
+    explicit GlyphCache();
+
     static void             InitFreetype();
     void                    GarbageCollect();
     FreetypeFont*           CreateFont(LogicalFontInstance* pLogicalFont);
+    FreetypeFontFile* FindFontFile(const OString& rNativeFileName);
 
     // the GlyphCache's FontList matches a font request to a serverfont instance
     // the FontList key's mpFontData member is reinterpreted as integer font id
@@ -78,6 +109,7 @@ private:
     struct IFSD_Hash{ size_t operator()( const rtl::Reference<LogicalFontInstance>& ) const; };
     typedef std::unordered_map<rtl::Reference<LogicalFontInstance>,std::unique_ptr<FreetypeFont>,IFSD_Hash,IFSD_Equal > FontList;
     typedef std::unordered_map<sal_IntPtr, std::unique_ptr<FreetypeFontInfo>> FontInfoList;
+    typedef std::unordered_map<const char*, std::unique_ptr<FreetypeFontFile>, rtl::CStringHash, rtl::CStringEqual> FontFileList;
 
     FontList                maFontList;
     static constexpr sal_uLong gnMaxSize = 1500000;  // max overall cache size in bytes
@@ -86,12 +118,13 @@ private:
 
     FontInfoList            m_aFontInfoList;
     sal_IntPtr              m_nMaxFontId;
+
+    FontFileList            m_aFontFileList;
 };
 
 class FreetypeFont final
 {
 public:
-                            FreetypeFont(LogicalFontInstance* pFontInstance, FreetypeFontInfo*);
                             ~FreetypeFont();
 
     const OString&          GetFontFileName() const;
@@ -126,9 +159,7 @@ public:
 
 private:
     friend class GlyphCache;
-    friend class FreetypeFontInstance;
-    friend class X11SalGraphics;
-    friend class CairoTextRender;
+    explicit FreetypeFont(LogicalFontInstance*, FreetypeFontInfo*);
 
     void                    AddRef() const      { ++mnRefCount; }
     long                    GetRefCount() const { return mnRefCount; }
diff --git a/vcl/unx/generic/app/gendata.cxx b/vcl/unx/generic/app/gendata.cxx
index 2e376cc2e3f3..ea091105529a 100644
--- a/vcl/unx/generic/app/gendata.cxx
+++ b/vcl/unx/generic/app/gendata.cxx
@@ -25,7 +25,6 @@
 GenericUnixSalData::GenericUnixSalData(GenericUnixSalDataType const t, SalInstance* const pInstance)
     : m_eType(t)
     , m_pDisplay(nullptr)
-    , m_pGlyphCache(new GlyphCache)
 {
     m_pInstance = pInstance;
     SetSalData(this);
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index 96a6a9563435..6535c7c4b976 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -61,10 +61,6 @@
 
 static FT_Library aLibFT = nullptr;
 
-typedef std::unordered_map<const char*, std::shared_ptr<FreetypeFontFile>, rtl::CStringHash, rtl::CStringEqual> FontFileList;
-
-namespace { struct vclFontFileList : public rtl::Static< FontFileList, vclFontFileList > {}; }
-
 // TODO: remove when the priorities are selected by UI
 // if (AH==0) => disable autohinting
 // if (AA==0) => disable antialiasing
@@ -101,22 +97,6 @@ FreetypeFontFile::FreetypeFontFile( const OString& rNativeFileName )
     }
 }
 
-FreetypeFontFile* FreetypeFontFile::FindFontFile( const OString& rNativeFileName )
-{
-    // font file already known? (e.g. for ttc, synthetic, aliased fonts)
-    const char* pFileName = rNativeFileName.getStr();
-    FontFileList &rFontFileList = vclFontFileList::get();
-    FontFileList::const_iterator it = rFontFileList.find( pFileName );
-    if( it != rFontFileList.end() )
-        return it->second.get();
-
-    // no => create new one
-    FreetypeFontFile* pFontFile = new FreetypeFontFile( rNativeFileName );
-    pFileName = pFontFile->maNativeFileName.getStr();
-    rFontFileList[pFileName].reset(pFontFile);
-    return pFontFile;
-}
-
 bool FreetypeFontFile::Map()
 {
     if( mnRefCount++ <= 0 )
@@ -154,10 +134,10 @@ void FreetypeFontFile::Unmap()
 }
 
 FreetypeFontInfo::FreetypeFontInfo( const FontAttributes& rDevFontAttributes,
-    const OString& rNativeFileName, int nFaceNum, int nFaceVariation, sal_IntPtr nFontId)
+    FreetypeFontFile* const pFontFile, int nFaceNum, int nFaceVariation, sal_IntPtr nFontId)
 :
     maFaceFT( nullptr ),
-    mpFontFile( FreetypeFontFile::FindFontFile( rNativeFileName ) ),
+    mpFontFile(pFontFile),
     mnFaceNum( nFaceNum ),
     mnFaceVariation( nFaceVariation ),
     mnRefCount( 0 ),
@@ -310,8 +290,6 @@ void GlyphCache::InitFreetype()
     pEnv = ::getenv( "SAL_ANTIALIASED_TEXT_PRIORITY" );
     if( pEnv )
         nDefaultPrioAntiAlias = pEnv[0] - '0';
-
-    (void)vclFontFileList::get();
 }
 
 namespace
@@ -351,7 +329,7 @@ void GlyphCache::AddFontFile(const OString& rNormalizedName,
         return;
 
     FreetypeFontInfo* pFontInfo = new FreetypeFontInfo( rDevFontAttr,
-        rNormalizedName, nFaceNum, nVariantNum, nFontId);
+        FindFontFile(rNormalizedName), nFaceNum, nVariantNum, nFontId);
     m_aFontInfoList[ nFontId ].reset(pFontInfo);
     if( m_nMaxFontId < nFontId )
         m_nMaxFontId = nFontId;
diff --git a/vcl/unx/generic/glyphs/glyphcache.cxx b/vcl/unx/generic/glyphs/glyphcache.cxx
index 46be26d38971..34543b7731a0 100644
--- a/vcl/unx/generic/glyphs/glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/glyphcache.cxx
@@ -240,6 +240,21 @@ void GlyphCache::GarbageCollect()
     }
 }
 
+FreetypeFontFile* GlyphCache::FindFontFile(const OString& rNativeFileName)
+{
+    // font file already known? (e.g. for ttc, synthetic, aliased fonts)
+    const char* pFileName = rNativeFileName.getStr();
+    FontFileList::const_iterator it = m_aFontFileList.find(pFileName);
+    if (it != m_aFontFileList.end())
+        return it->second.get();
+
+    // no => create new one
+    FreetypeFontFile* pFontFile = new FreetypeFontFile(rNativeFileName);
+    pFileName = pFontFile->maNativeFileName.getStr();
+    m_aFontFileList[pFileName].reset(pFontFile);
+    return pFontFile;
+}
+
 void FreetypeFont::ReleaseFromGarbageCollect()
 {
     // remove from GC list


More information about the Libreoffice-commits mailing list