summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2018-04-24 08:36:58 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2018-04-26 08:48:06 +0200
commit13a1bc409d9b2f0d14f4d316b7977b1fc2eb3c8a (patch)
tree97c8f08726749007311263dad8280480bde449b9
parent96c1aad92b40a14d0d4af662e276b6967560ec20 (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.h1
-rw-r--r--vcl/win/gdi/salfont.cxx24
-rw-r--r--vcl/win/gdi/salgdi.cxx3
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));