diff options
-rw-r--r-- | vcl/inc/unx/glyphcache.hxx | 35 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/cairotextrender.cxx | 4 | ||||
-rw-r--r-- | vcl/unx/generic/glyphs/freetype_glyphcache.cxx | 19 | ||||
-rw-r--r-- | vcl/unx/generic/glyphs/glyphcache.cxx | 79 | ||||
-rw-r--r-- | vcl/unx/generic/print/genpspgraphics.cxx | 3 |
5 files changed, 20 insertions, 120 deletions
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx index 446acc2944af..9fe3bd3dc7cf 100644 --- a/vcl/inc/unx/glyphcache.hxx +++ b/vcl/inc/unx/glyphcache.hxx @@ -41,7 +41,6 @@ class FreetypeFont; class FreetypeFontInstance; class FreetypeFontInfo; -class GlyphData; class FontConfigFontOptions; class PhysicalFontCollection; class FreetypeFont; @@ -71,13 +70,6 @@ public: void ClearFontOptions(); private: - friend class FreetypeFont; - // used by FreetypeFont class only - void AddedGlyph( GlyphData& ); - void RemovingGlyph(); - void UsingGlyph( GlyphData const & ); - -private: void InitFreetype(); void GarbageCollect(); FreetypeFont* CreateFont(LogicalFontInstance* pLogicalFont); @@ -92,32 +84,12 @@ private: FontList maFontList; static constexpr sal_uLong gnMaxSize = 1500000; // max overall cache size in bytes mutable sal_uLong mnBytesUsed; - mutable long mnLruIndex; - mutable int mnGlyphCount; FreetypeFont* mpCurrentGCFont; FontInfoList m_aFontInfoList; sal_IntPtr m_nMaxFontId; }; -class GlyphData -{ -public: - GlyphData() : mnLruValue(0) {} - - const tools::Rectangle& GetBoundRect() const { return maBoundRect; } - void SetBoundRect(tools::Rectangle r) { maBoundRect = r; } - - void SetLruValue( int n ) const { mnLruValue = n; } - long GetLruValue() const { return mnLruValue;} - -private: - tools::Rectangle maBoundRect; - - // used by GlyphCache for cache LRU algorithm - mutable long mnLruValue; -}; - class VCL_DLLPUBLIC FreetypeFont final { public: @@ -139,7 +111,7 @@ public: const FontCharMapRef GetFontCharMap() const; bool GetFontCapabilities(vcl::FontCapabilities &) const; - const tools::Rectangle& GetGlyphBoundRect(const GlyphItem& rGlyph); + bool GetGlyphBoundRect(const GlyphItem&, tools::Rectangle&); bool GetGlyphOutline(const GlyphItem& rGlyph, basegfx::B2DPolyPolygon&) const; bool GetAntialiasAdvice() const; @@ -156,15 +128,10 @@ private: long Release() const; sal_uLong GetByteCount() const { return mnBytesUsed; } - void InitGlyphData(const GlyphItem&, GlyphData&) const; - void GarbageCollect( long ); void ReleaseFromGarbageCollect(); void ApplyGlyphTransform(bool bVertical, FT_Glyph) const; - typedef std::unordered_map<sal_GlyphId, GlyphData> GlyphList; - mutable GlyphList maGlyphList; - rtl::Reference<FreetypeFontInstance> mpFontInstance; // used by GlyphCache for cache LRU algorithm diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index 11d4e94592c4..40e1c5a8db3b 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -451,7 +451,9 @@ bool CairoTextRender::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangl if( !pSF ) return false; - tools::Rectangle aRect = pSF->GetGlyphBoundRect(rGlyph); + tools::Rectangle aRect; + if (!pSF->GetGlyphBoundRect(rGlyph, aRect)) + return false; if ( pSF->mnCos != 0x10000 && pSF->mnSin != 0 ) { diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx index cfc91deb07e0..8a5314ff697b 100644 --- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx +++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx @@ -347,8 +347,7 @@ rtl::Reference<LogicalFontInstance> FreetypeFontFace::CreateFontInstance(const F // FreetypeFont FreetypeFont::FreetypeFont(LogicalFontInstance* pFontInstance, FreetypeFontInfo* pFI ) -: maGlyphList( 0), - mpFontInstance(static_cast<FreetypeFontInstance*>(pFontInstance)), +: mpFontInstance(static_cast<FreetypeFontInstance*>(pFontInstance)), mnRefCount(1), mnBytesUsed( sizeof(FreetypeFont) ), mpPrevGCFont( nullptr ), @@ -589,14 +588,18 @@ void FreetypeFont::ApplyGlyphTransform(bool bVertical, FT_Glyph pGlyphFT ) const } } -void FreetypeFont::InitGlyphData(const GlyphItem& rGlyph, GlyphData& rGD ) const +bool FreetypeFont::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle& rRect) { + assert(mpFontInstance.is()); + if (mpFontInstance.is() && mpFontInstance->GetCachedGlyphBoundRect(rGlyph.maGlyphId, rRect)) + return true; + FT_Activate_Size( maSizeFT ); FT_Error rc = FT_Load_Glyph(maFaceFT, rGlyph.maGlyphId, mnLoadFlags); if (rc != FT_Err_Ok) - return; + return false; if (mbArtBold) FT_GlyphSlot_Embolden(maFaceFT->glyph); @@ -604,16 +607,20 @@ void FreetypeFont::InitGlyphData(const GlyphItem& rGlyph, GlyphData& rGD ) const FT_Glyph pGlyphFT; rc = FT_Get_Glyph(maFaceFT->glyph, &pGlyphFT); if (rc != FT_Err_Ok) - return; + return false; ApplyGlyphTransform(rGlyph.IsVertical(), pGlyphFT); FT_BBox aBbox; FT_Glyph_Get_CBox( pGlyphFT, FT_GLYPH_BBOX_PIXELS, &aBbox ); - rGD.SetBoundRect(tools::Rectangle(aBbox.xMin, -aBbox.yMax, aBbox.xMax, -aBbox.yMin)); + rRect = tools::Rectangle(aBbox.xMin, -aBbox.yMax, aBbox.xMax, -aBbox.yMin); + if (mpFontInstance.is()) + mpFontInstance->CacheGlyphBoundRect(rGlyph.maGlyphId, rRect); FT_Done_Glyph( pGlyphFT ); + + return true; } bool FreetypeFont::GetAntialiasAdvice() const diff --git a/vcl/unx/generic/glyphs/glyphcache.cxx b/vcl/unx/generic/glyphs/glyphcache.cxx index 5bdcf9ac7491..c4bf10ac76c0 100644 --- a/vcl/unx/generic/glyphs/glyphcache.cxx +++ b/vcl/unx/generic/glyphs/glyphcache.cxx @@ -33,8 +33,6 @@ GlyphCache::GlyphCache() : mnBytesUsed(sizeof(GlyphCache)), - mnLruIndex(0), - mnGlyphCount(0), mpCurrentGCFont(nullptr) , m_nMaxFontId(0) { @@ -48,14 +46,6 @@ GlyphCache::~GlyphCache() void GlyphCache::ClearFontCache() { - for (auto& font : maFontList) - { - FreetypeFont* pFreetypeFont = font.second.get(); - // free all pFreetypeFont related data - pFreetypeFont->GarbageCollect( mnLruIndex+0x10000000 ); - font.second.reset(); - } - maFontList.clear(); mpCurrentGCFont = nullptr; m_aFontInfoList.clear(); @@ -206,10 +196,7 @@ FreetypeFont* GlyphCache::CacheFont(LogicalFontInstance* pFontInstance) void GlyphCache::UncacheFont( FreetypeFont& rFreetypeFont ) { if( (rFreetypeFont.Release() <= 0) && (gnMaxSize <= mnBytesUsed) ) - { mpCurrentGCFont = &rFreetypeFont; - GarbageCollect(); - } } void GlyphCache::GarbageCollect() @@ -230,19 +217,13 @@ void GlyphCache::GarbageCollect() FreetypeFont* const pFreetypeFont = mpCurrentGCFont; mpCurrentGCFont = pFreetypeFont->mpNextGCFont; - if( (pFreetypeFont == mpCurrentGCFont) // no other fonts - || (pFreetypeFont->GetRefCount() > 0) ) // font still used - { - // try to garbage collect at least a few bytes - pFreetypeFont->GarbageCollect( mnLruIndex - mnGlyphCount/2 ); - } - else // current GC font is unreferenced + if( (pFreetypeFont != mpCurrentGCFont) // no other fonts + && (pFreetypeFont->GetRefCount() <= 0) ) // font still used { SAL_WARN_IF( (pFreetypeFont->GetRefCount() != 0), "vcl", "GlyphCache::GC detected RefCount underflow" ); // free all pFreetypeFont related data - pFreetypeFont->GarbageCollect( mnLruIndex+0x10000000 ); if( pFreetypeFont == mpCurrentGCFont ) mpCurrentGCFont = nullptr; mnBytesUsed -= pFreetypeFont->GetByteCount(); @@ -259,26 +240,6 @@ void GlyphCache::GarbageCollect() } } -inline void GlyphCache::UsingGlyph( GlyphData const & rGlyphData ) -{ - rGlyphData.SetLruValue( mnLruIndex++ ); -} - -inline void GlyphCache::AddedGlyph( GlyphData& rGlyphData ) -{ - ++mnGlyphCount; - mnBytesUsed += sizeof( rGlyphData ); - UsingGlyph( rGlyphData ); - if( mnBytesUsed > gnMaxSize ) - GarbageCollect(); -} - -inline void GlyphCache::RemovingGlyph() -{ - mnBytesUsed -= sizeof( GlyphData ); - --mnGlyphCount; -} - void FreetypeFont::ReleaseFromGarbageCollect() { // remove from GC list @@ -296,42 +257,6 @@ long FreetypeFont::Release() const return --mnRefCount; } -const tools::Rectangle& FreetypeFont::GetGlyphBoundRect(const GlyphItem& rGlyph) -{ - // usually the GlyphData is cached - GlyphList::iterator it = maGlyphList.find(rGlyph.maGlyphId); - if( it != maGlyphList.end() ) { - GlyphData& rGlyphData = it->second; - GlyphCache::GetInstance().UsingGlyph( rGlyphData ); - return rGlyphData.GetBoundRect(); - } - - // sometimes not => we need to create and initialize it ourselves - GlyphData& rGlyphData = maGlyphList[rGlyph.maGlyphId]; - mnBytesUsed += sizeof( GlyphData ); - InitGlyphData(rGlyph, rGlyphData); - GlyphCache::GetInstance().AddedGlyph( rGlyphData ); - return rGlyphData.GetBoundRect(); -} - -void FreetypeFont::GarbageCollect( long nMinLruIndex ) -{ - GlyphList::iterator it = maGlyphList.begin(); - while( it != maGlyphList.end() ) - { - GlyphData& rGD = it->second; - if( (nMinLruIndex - rGD.GetLruValue()) > 0 ) - { - OSL_ASSERT( mnBytesUsed >= sizeof(GlyphData) ); - mnBytesUsed -= sizeof( GlyphData ); - GlyphCache::GetInstance().RemovingGlyph(); - it = maGlyphList.erase( it ); - } - else - ++it; - } -} - FreetypeFontInstance::FreetypeFontInstance(const PhysicalFontFace& rPFF, const FontSelectPattern& rFSP) : LogicalFontInstance(rPFF, rFSP) , mpFreetypeFont(nullptr) diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx index 88e7fcdf901a..ae30cfad6286 100644 --- a/vcl/unx/generic/print/genpspgraphics.cxx +++ b/vcl/unx/generic/print/genpspgraphics.cxx @@ -742,8 +742,7 @@ bool GenPspGraphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle if( !pSF ) return false; - rRect = pSF->GetGlyphBoundRect(rGlyph); - return true; + return pSF->GetGlyphBoundRect(rGlyph, rRect); } bool GenPspGraphics::GetGlyphOutline(const GlyphItem& rGlyph, |