summaryrefslogtreecommitdiff
path: root/vcl/unx/generic
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2018-10-04 13:25:06 +0000
committerJan-Marek Glogowski <glogow@fbihome.de>2018-10-06 20:13:28 +0200
commitdd36db168c658ebe588396255ad61363cc4ea7af (patch)
treeeb69c3c23b1ff05474ba075514d037ffe96f4bd4 /vcl/unx/generic
parent2f182faaf08542e381a1aee4544b47c4cd7c0b92 (diff)
UNX use font cache based glyph rect cache
Drop the special / duplicate glyph rect bound cache implementation for Freetype fonts. The GlyphCache class now looks a lot like the ImplFontCache class. The lru handling for Freetype fonts is based on the byte / memory size, including the glyth bound-rect caching. Using the new common cache is effectivly removing the bound-rects from this accounting, so the garbage collection won't free them anymore. Change-Id: Ie53226596ee2287e1059a74885f52c3d64bbccaa Reviewed-on: https://gerrit.libreoffice.org/61377 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'vcl/unx/generic')
-rw-r--r--vcl/unx/generic/gdi/cairotextrender.cxx4
-rw-r--r--vcl/unx/generic/glyphs/freetype_glyphcache.cxx19
-rw-r--r--vcl/unx/generic/glyphs/glyphcache.cxx79
-rw-r--r--vcl/unx/generic/print/genpspgraphics.cxx3
4 files changed, 19 insertions, 86 deletions
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,