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 <n...@peralex.com> AuthorDate: Fri Nov 22 13:32:17 2019 +0200 Commit: Noel Grandin <noel.gran...@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.gran...@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; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits