diff options
author | Noel Grandin <noel@peralex.com> | 2018-04-24 08:36:58 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-04-26 08:48:06 +0200 |
commit | 13a1bc409d9b2f0d14f4d316b7977b1fc2eb3c8a (patch) | |
tree | 97c8f08726749007311263dad8280480bde449b9 | |
parent | 96c1aad92b40a14d0d4af662e276b6967560ec20 (diff) |
tdf#113643 Editing tables in Impress lags terribly
Despite my previous commit here, the time was still being spent building
bound rect's for font glyphs, so improve the caching so we don't need to
clear it when we change the font selected into the DC.
Change-Id: Iee8230fc76d9d809f3521d016e4ce9a6555e6f65
Reviewed-on: https://gerrit.libreoffice.org/53371
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Tested-by: Noel Grandin <noel.grandin@collabora.co.uk>
-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)); |