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