summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2018-04-09 11:16:59 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2018-04-11 10:07:19 +0200
commit8a94d3dcfa0c37685afd5f966d7fdc1d25dc923d (patch)
treea0b8a09ff88735e58a5155f9b1bb5c803c475707
parent40f1cfa6a7d9f8c501cd4e940f8a047b4162fb03 (diff)
tdf#108608 more Draw text editing responsiveness fixes
Turns out Windows is rather slow at at calculating glyph outlines (compared to Linux), I'm guessing it does no caching at all, so just add our own little cache. I tried to use o3tl::lru_map here, but it crashes under MSVC2015. Change-Id: I78d2a787ec8f734fa821f41f13236771efa1c8d4 Reviewed-on: https://gerrit.libreoffice.org/52623 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r--include/o3tl/lru_map.hxx5
-rw-r--r--vcl/win/gdi/salfont.cxx19
2 files changed, 24 insertions, 0 deletions
diff --git a/include/o3tl/lru_map.hxx b/include/o3tl/lru_map.hxx
index 2f41521795fc..4eb05bd97a43 100644
--- a/include/o3tl/lru_map.hxx
+++ b/include/o3tl/lru_map.hxx
@@ -132,6 +132,11 @@ public:
{
return mLruList.size();
}
+
+ void clear()
+ {
+ mLruList.clear();
+ }
};
}
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 9dbde8fd52d7..e415ec8fa1b3 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -56,6 +56,11 @@
using namespace vcl;
+// GetGlyphOutlineW() seems to be a little slow, and doesn't seem to do it's own caching (tested on Windows10).
+// TODO use something a little smarter here like an LRU cache, and include the font as part of the cache key
+// The cache limit is set by the rough number of characters needed to read your average Asian newspaper.
+constexpr size_t BOUND_RECT_CACHE_SIZE = 3000;
+static std::unordered_map<sal_GlyphId, tools::Rectangle> g_BoundRectCache;
inline FIXED FixedFromDouble( double d )
{
@@ -835,6 +840,9 @@ void ImplGetLogFontFromFontSelect( HDC hDC,
HFONT WinSalGraphics::ImplDoSetFont(FontSelectPattern const * i_pFont, HFONT& o_rOldFont)
{
+ // clear the cache on font change
+ g_BoundRectCache.clear();
+
HFONT hNewFont = nullptr;
HDC hdcScreen = nullptr;
@@ -1326,6 +1334,15 @@ void WinSalGraphics::ClearDevFontCache()
bool WinSalGraphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle& rRect)
{
+ auto it = g_BoundRectCache.find(rGlyph.maGlyphId);
+ if (it != g_BoundRectCache.end())
+ {
+ rRect = it->second;
+ return true;
+ }
+ if (g_BoundRectCache.size() > BOUND_RECT_CACHE_SIZE)
+ g_BoundRectCache.clear();
+
HDC hDC = getHDC();
// use unity matrix
@@ -1347,6 +1364,8 @@ bool WinSalGraphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle
Size( aGM.gmBlackBoxX, aGM.gmBlackBoxY ) );
rRect.AdjustRight(1);
rRect.AdjustBottom(1);
+
+ g_BoundRectCache.insert({rGlyph.maGlyphId, rRect});
return true;
}