summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}