summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2019-11-22 13:32:17 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2019-11-22 20:31:37 +0100
commit90ea305110e5881256ba272800074a2a9f6b613d (patch)
treef6377700e996937e919948ccc94032e36e028d50
parent5f520f757774db17ea4e33d34c724cf2af3adcba (diff)
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@collabora.co.uk>
-rw-r--r--vcl/inc/fontinstance.hxx1
-rw-r--r--vcl/inc/win/winlayout.hxx1
-rw-r--r--vcl/win/gdi/winlayout.cxx53
3 files changed, 50 insertions, 5 deletions
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;
}