Cache font widths in CFX_GlyphCache
Rendering text with Skia results in many font widths lookups, which can
cause performance slow downs. Since many lookups are redundant, mitigate
this issue by making CFX_GlyphCache cache the font width data.
The same cache may help with performance in general, as other code paths
do font widths lookups as well.
Change-Id: I847e1fa0d3a5e7a3993a8cbdae6caf56be0ea827
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/106370
Reviewed-by: Nigi <nigi@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index d5a674c..e9ca56b 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -418,6 +418,13 @@
int CFX_Font::GetGlyphWidth(uint32_t glyph_index,
int dest_width,
int weight) const {
+ return GetOrCreateGlyphCache()->GetGlyphWidth(this, glyph_index, dest_width,
+ weight);
+}
+
+int CFX_Font::GetGlyphWidthImpl(uint32_t glyph_index,
+ int dest_width,
+ int weight) const {
if (!m_Face)
return 0;
if (m_pSubstFont && m_pSubstFont->IsBuiltInGenericFont())
diff --git a/core/fxge/cfx_font.h b/core/fxge/cfx_font.h
index 944cf79..bf94874 100644
--- a/core/fxge/cfx_font.h
+++ b/core/fxge/cfx_font.h
@@ -137,6 +137,7 @@
void AdjustMMParams(int glyph_index, int dest_width, int weight) const;
std::unique_ptr<CFX_Path> LoadGlyphPathImpl(uint32_t glyph_index,
int dest_width) const;
+ int GetGlyphWidthImpl(uint32_t glyph_index, int dest_width, int weight) const;
#if defined(_SKIA_SUPPORT_)
CFX_TypeFace* GetDeviceCache() const;
diff --git a/core/fxge/cfx_glyphcache.cpp b/core/fxge/cfx_glyphcache.cpp
index 55cf873..e923f3c 100644
--- a/core/fxge/cfx_glyphcache.cpp
+++ b/core/fxge/cfx_glyphcache.cpp
@@ -312,6 +312,20 @@
#endif // BUILDFLAG(IS_APPLE)
}
+int CFX_GlyphCache::GetGlyphWidth(const CFX_Font* font,
+ uint32_t glyph_index,
+ int dest_width,
+ int weight) {
+ const WidthMapKey key = std::make_tuple(glyph_index, dest_width, weight);
+ auto it = m_WidthMap.find(key);
+ if (it != m_WidthMap.end()) {
+ return it->second;
+ }
+
+ m_WidthMap[key] = font->GetGlyphWidthImpl(glyph_index, dest_width, weight);
+ return m_WidthMap[key];
+}
+
#if defined(_SKIA_SUPPORT_)
CFX_TypeFace* CFX_GlyphCache::GetDeviceCache(const CFX_Font* pFont) {
if (!m_pTypeface) {
diff --git a/core/fxge/cfx_glyphcache.h b/core/fxge/cfx_glyphcache.h
index a57b770..99a0604 100644
--- a/core/fxge/cfx_glyphcache.h
+++ b/core/fxge/cfx_glyphcache.h
@@ -42,6 +42,10 @@
const CFX_Path* LoadGlyphPath(const CFX_Font* pFont,
uint32_t glyph_index,
int dest_width);
+ int GetGlyphWidth(const CFX_Font* font,
+ uint32_t glyph_index,
+ int dest_width,
+ int weight);
RetainPtr<CFX_Face> GetFace() { return m_Face; }
FXFT_FaceRec* GetFaceRec() { return m_Face ? m_Face->GetRec() : nullptr; }
@@ -56,6 +60,8 @@
using SizeGlyphCache = std::map<uint32_t, std::unique_ptr<CFX_GlyphBitmap>>;
// <glyph_index, width, weight, angle, vertical>
using PathMapKey = std::tuple<uint32_t, int, int, int, bool>;
+ // <glyph_index, dest_width, weight>
+ using WidthMapKey = std::tuple<uint32_t, int, int>;
std::unique_ptr<CFX_GlyphBitmap> RenderGlyph(const CFX_Font* pFont,
uint32_t glyph_index,
@@ -82,6 +88,7 @@
RetainPtr<CFX_Face> const m_Face;
std::map<ByteString, SizeGlyphCache> m_SizeMap;
std::map<PathMapKey, std::unique_ptr<CFX_Path>> m_PathMap;
+ std::map<WidthMapKey, int> m_WidthMap;
#if defined(_SKIA_SUPPORT_)
sk_sp<SkTypeface> m_pTypeface;
#endif