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 <[email protected]> AuthorDate: Fri Nov 15 16:19:31 2019 +0000 Commit: Jan-Marek Glogowski <[email protected]> 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 <[email protected]> (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 _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
