[Libreoffice-commits] core.git: vcl/inc vcl/win

Noel Grandin noel at peralex.com
Thu Apr 26 06:48:47 UTC 2018


 vcl/inc/win/salgdi.h    |    1 +
 vcl/win/gdi/salfont.cxx |   24 +++++++++++++++++-------
 vcl/win/gdi/salgdi.cxx  |    3 ++-
 3 files changed, 20 insertions(+), 8 deletions(-)

New commits:
commit 13a1bc409d9b2f0d14f4d316b7977b1fc2eb3c8a
Author: Noel Grandin <noel at peralex.com>
Date:   Tue Apr 24 08:36:58 2018 +0200

    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 at collabora.co.uk>
    Tested-by: Noel Grandin <noel.grandin at collabora.co.uk>

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));


More information about the Libreoffice-commits mailing list