diff options
-rw-r--r-- | vcl/inc/win/salgdi.h | 1 | ||||
-rw-r--r-- | vcl/win/gdi/salfont.cxx | 24 | ||||
-rw-r--r-- | vcl/win/gdi/salgdi.cxx | 3 |
3 files changed, 20 insertions, 8 deletions
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 23531842dde3..f45d85c4c89c 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -177,6 +177,7 @@ private: RGNDATA* mpClipRgnData; // ClipRegion-Data RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data int mnPenWidth; // line width + const PhysicalFontFace* mpCurrentPhysicalFontFace; // the font face currently selected into the DC LogicalFontInstance* GetWinFontEntry(int nFallbackLevel); diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 6fe84173c710..0acdbd666bef 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -57,10 +57,22 @@ using namespace vcl; +using BoundRectCacheKey = std::pair<PhysicalFontFace const *,sal_GlyphId>; +namespace std +{ + template<> struct hash<BoundRectCacheKey> + { + std::size_t operator()(const BoundRectCacheKey & key ) const + { + return std::hash<PhysicalFontFace const *>()(key.first) + ^ std::hash<sal_GlyphId>()(key.second); + } + }; +}; // GetGlyphOutlineW() seems to be a little slow, and doesn't seem to do it's own caching (tested on Windows10). // TODO include the font as part of the cache key, then we won't need to clear it on font change // The cache limit is set by the rough number of characters needed to read your average Asian newspaper. -static o3tl::lru_map<sal_GlyphId, tools::Rectangle> g_BoundRectCache(3000); +static o3tl::lru_map<BoundRectCacheKey, tools::Rectangle> g_BoundRectCache(3000); static const int MAXFONTHEIGHT = 2048; @@ -840,10 +852,9 @@ void ImplGetLogFontFromFontSelect( HDC hDC, HFONT WinSalGraphics::ImplDoSetFont(FontSelectPattern const * i_pFont, float& o_rFontScale, HFONT& o_rOldFont) { - // clear the cache on font change - g_BoundRectCache.clear(); - HFONT hNewFont = nullptr; + mpCurrentPhysicalFontFace = i_pFont->mpFontData; + HFONT hNewFont = nullptr; HDC hdcScreen = nullptr; if( mbVirDev ) // only required for virtual devices, see below for details @@ -1355,7 +1366,7 @@ void WinSalGraphics::ClearDevFontCache() bool WinSalGraphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle& rRect) { - auto it = g_BoundRectCache.find(rGlyph.maGlyphId); + auto it = g_BoundRectCache.find({mpCurrentPhysicalFontFace,rGlyph.maGlyphId}); if (it != g_BoundRectCache.end()) { rRect = it->second; @@ -1386,8 +1397,7 @@ bool WinSalGraphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle rRect.SetTop(static_cast<int>( mfCurrentFontScale * rRect.Top() )); rRect.SetBottom(static_cast<int>( mfCurrentFontScale * rRect.Bottom() ) + 1); - g_BoundRectCache.insert({rGlyph.maGlyphId, rRect}); - + g_BoundRectCache.insert({{mpCurrentPhysicalFontFace,rGlyph.maGlyphId}, rRect}); return true; } diff --git a/vcl/win/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx index 8aa601a461b2..890b28cc0c57 100644 --- a/vcl/win/gdi/salgdi.cxx +++ b/vcl/win/gdi/salgdi.cxx @@ -614,7 +614,8 @@ WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hW mhDefFont(nullptr), mhDefPal(nullptr), mpStdClipRgnData(nullptr), - mnPenWidth(GSL_PEN_WIDTH) + mnPenWidth(GSL_PEN_WIDTH), + mpCurrentPhysicalFontFace(nullptr) { if (OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter) mpImpl.reset(new WinOpenGLSalGraphicsImpl(*this, pProvider)); |