[Libreoffice-commits] core.git: Branch 'libreoffice-6-4' - vcl/inc vcl/win

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Sun Nov 24 07:45:38 UTC 2019


 vcl/inc/fontinstance.hxx  |    1 
 vcl/inc/win/winlayout.hxx |    1 
 vcl/win/gdi/winlayout.cxx |   53 +++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 50 insertions(+), 5 deletions(-)

New commits:
commit 29d2024e16ce3cb81ad7f5b5f7e1b93378a93199
Author:     Noel Grandin <noel at peralex.com>
AuthorDate: Fri Nov 22 13:32:17 2019 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Sun Nov 24 08:44:51 2019 +0100

    tdf#121740 cache font data to speed up PPT load
    
    takes the load time from 24s to 21s for me.
    The cache was determined experimentally for this document.
    
    Change-Id: I34c78d1ff99cb8e72b274a201ded61d23e66941a
    Reviewed-on: https://gerrit.libreoffice.org/83470
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
    (cherry picked from commit 90ea305110e5881256ba272800074a2a9f6b613d)
    Reviewed-on: https://gerrit.libreoffice.org/83542

diff --git a/vcl/inc/fontinstance.hxx b/vcl/inc/fontinstance.hxx
index ed4d92e8ef57..b4d7da663090 100644
--- a/vcl/inc/fontinstance.hxx
+++ b/vcl/inc/fontinstance.hxx
@@ -71,6 +71,7 @@ public: // TODO: make data members private
     const FontSelectPattern& GetFontSelectPattern() const { return m_aFontSelData; }
 
     const PhysicalFontFace* GetFontFace() const { return m_pFontFace.get(); }
+    PhysicalFontFace* GetFontFace() { return m_pFontFace.get(); }
     const ImplFontCache* GetFontCache() const { return mpFontCache; }
 
     bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const;
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 991c68f15b66..035998e2bcd9 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -164,6 +164,7 @@ public:
     void SetHFONT(HFONT hFont) { m_hFont = hFont; }
 
     const WinFontFace * GetFontFace() const { return static_cast<const WinFontFace *>(LogicalFontInstance::GetFontFace()); }
+    WinFontFace * GetFontFace() { return static_cast<WinFontFace *>(LogicalFontInstance::GetFontFace()); }
 
     bool CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics, const GenericSalLayout& rLayout);
     OpenGLGlyphCache& GetOpenGLGlyphCache() { return maOpenGLGlyphCache; }
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index b67f191c0b47..9f4da1950245 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -1,3 +1,4 @@
+
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*
  * This file is part of the LibreOffice project.
@@ -44,6 +45,7 @@
 
 #include <rtl/character.hxx>
 
+#include <boost/functional/hash.hpp>
 #include <algorithm>
 
 #include <shlwapi.h>
@@ -327,16 +329,53 @@ float WinFontInstance::getHScale() const
     return nWidth / nHeight;
 }
 
+struct BlobReference
+{
+    hb_blob_t* mpBlob;
+    BlobReference(hb_blob_t* pBlob) : mpBlob(pBlob)
+    {
+        hb_blob_reference(mpBlob);
+    }
+    BlobReference(BlobReference const & other)
+        : mpBlob(other.mpBlob)
+    {
+        hb_blob_reference(mpBlob);
+    }
+    ~BlobReference() { hb_blob_destroy(mpBlob); }
+};
+using BlobCacheKey = std::pair<rtl::Reference<PhysicalFontFace>, hb_tag_t>;
+struct BlobCacheKeyHash
+{
+    std::size_t operator()(BlobCacheKey const& rKey) const
+    {
+        std::size_t seed = 0;
+        boost::hash_combine(seed, rKey.first.get());
+        boost::hash_combine(seed, rKey.second);
+        return seed;
+    }
+};
+
 static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pUserData)
 {
-    sal_uLong nLength = 0;
-    unsigned char* pBuffer = nullptr;
+    static o3tl::lru_map<BlobCacheKey, BlobReference, BlobCacheKeyHash> gCache(50);
+
     WinFontInstance* pFont = static_cast<WinFontInstance*>(pUserData);
     HDC hDC = pFont->GetGraphics()->getHDC();
     HFONT hFont = pFont->GetHFONT();
     assert(hDC);
     assert(hFont);
 
+    BlobCacheKey cacheKey { rtl::Reference<PhysicalFontFace>(pFont->GetFontFace()), nTableTag };
+    auto it = gCache.find(cacheKey);
+    if (it != gCache.end())
+    {
+        hb_blob_reference(it->second.mpBlob);
+        return it->second.mpBlob;
+    }
+
+    sal_uLong nLength = 0;
+    unsigned char* pBuffer = nullptr;
+
     HGDIOBJ hOrigFont = SelectObject(hDC, hFont);
     nLength = ::GetFontData(hDC, OSL_NETDWORD(nTableTag), 0, nullptr, 0);
     if (nLength > 0 && nLength != GDI_ERROR)
@@ -346,10 +385,14 @@ static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
     }
     SelectObject(hDC, hOrigFont);
 
-    hb_blob_t* pBlob = nullptr;
-    if (pBuffer != nullptr)
-        pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY,
+    if (!pBuffer)
+        return nullptr;
+
+    hb_blob_t* pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY,
                                pBuffer, [](void* data){ delete[] static_cast<unsigned char*>(data); });
+    if (!pBlob)
+        return pBlob;
+    gCache.insert({cacheKey, BlobReference(pBlob)});
     return pBlob;
 }
 


More information about the Libreoffice-commits mailing list