7#include "core/fxge/cfx_glyphcache.h"
9#include <initializer_list>
13#include "build/build_config.h"
14#include "core/fxcrt/fx_codepage.h"
15#include "core/fxcrt/fx_memcpy_wrappers.h"
16#include "core/fxcrt/span.h"
17#include "core/fxge/cfx_defaultrenderdevice.h"
18#include "core/fxge/cfx_font.h"
19#include "core/fxge/cfx_glyphbitmap.h"
20#include "core/fxge/cfx_path.h"
21#include "core/fxge/cfx_substfont.h"
23#if defined(PDF_USE_SKIA)
24#include "third_party/skia/include/core/SkStream.h"
25#include "third_party/skia/include/core/SkTypeface.h"
26#include "third_party/skia/include/core/SkFontMgr.h"
27#include "third_party/skia/include/ports/SkFontMgr_empty.h"
30#include "third_party/skia/include/ports/SkTypeface_win.h"
31#elif BUILDFLAG(IS_APPLE)
32#include "third_party/skia/include/ports/SkFontMgr_mac_ct.h"
37#if BUILDFLAG(IS_APPLE)
38#include "core/fxge/cfx_textrenderoptions.h"
43constexpr uint32_t kInvalidGlyphIndex =
static_cast<uint32_t>(-1);
53 pdfium::span<
const uint8_t> span()
const;
56 void Initialize(
std::initializer_list<
const int> args);
62void UniqueKeyGen::Initialize(
std::initializer_list<
const int32_t> args) {
63 auto key_span =
pdfium::make_span(key_);
64 for (
const auto& arg : args) {
65 key_span.front() = arg;
66 key_span = key_span.subspan(1);
68 key_len_ = args.size();
71pdfium::span<
const uint8_t> UniqueKeyGen::span()
const {
72 return pdfium::as_bytes(pdfium::make_span(key_).first(key_len_));
75UniqueKeyGen::UniqueKeyGen(
const CFX_Font* pFont,
80 int nMatrixA =
static_cast<
int>(matrix
.a * 10000);
81 int nMatrixB =
static_cast<
int>(matrix
.b * 10000);
82 int nMatrixC =
static_cast<
int>(matrix
.c * 10000);
83 int nMatrixD =
static_cast<
int>(matrix
.d * 10000);
85#if BUILDFLAG(IS_APPLE)
87 if (pFont->GetSubstFont()) {
88 Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
89 anti_alias, pFont->GetSubstFont()->m_Weight,
90 pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical(),
94 {nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, anti_alias, 3});
102 Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, anti_alias,
107 {nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, anti_alias});
113CFX_GlyphCache::CFX_GlyphCache(
RetainPtr<CFX_Face> face)
114 : m_Face(std::move(face)) {}
118std::unique_ptr<CFX_GlyphBitmap> CFX_GlyphCache::RenderGlyph(
120 uint32_t glyph_index,
129 return m_Face->RenderGlyph(pFont, glyph_index, bFontStyle, matrix, dest_width,
134 uint32_t glyph_index,
136 if (!GetFace() || glyph_index == kInvalidGlyphIndex) {
141 int weight = pSubstFont ? pSubstFont
->m_Weight : 0;
144 const PathMapKey key =
145 std::make_tuple(glyph_index, dest_width, weight, angle, vertical);
146 auto it = m_PathMap.find(key);
147 if (it != m_PathMap.end())
148 return it->second.get();
150 m_PathMap[key] = pFont->LoadGlyphPathImpl(glyph_index, dest_width);
151 return m_PathMap[key].get();
156 uint32_t glyph_index,
162 if (glyph_index == kInvalidGlyphIndex)
165#if BUILDFLAG(IS_APPLE)
166 const bool bNative = text_options->native_text;
168 const bool bNative =
false;
170 UniqueKeyGen keygen(pFont, matrix, dest_width, anti_alias, bNative);
173#if BUILDFLAG(IS_APPLE)
174 const bool bDoLookUp =
175 !text_options->native_text || CFX_DefaultRenderDevice::UseSkiaRenderer();
177 const bool bDoLookUp =
true;
180 return LookUpGlyphBitmap(pFont, matrix, FaceGlyphsKey, glyph_index,
181 bFontStyle, dest_width, anti_alias);
184#if BUILDFLAG(IS_APPLE)
185 DCHECK(!CFX_DefaultRenderDevice::UseSkiaRenderer());
187 std::unique_ptr<CFX_GlyphBitmap> pGlyphBitmap;
188 auto it = m_SizeMap.find(FaceGlyphsKey);
189 if (it != m_SizeMap.end()) {
190 SizeGlyphCache* pSizeCache = &(it->second);
191 auto it2 = pSizeCache->find(glyph_index);
192 if (it2 != pSizeCache->end())
193 return it2->second.get();
195 pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, matrix,
196 dest_width, anti_alias);
198 CFX_GlyphBitmap* pResult = pGlyphBitmap.get();
199 (*pSizeCache)[glyph_index] = std::move(pGlyphBitmap);
203 pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, matrix,
204 dest_width, anti_alias);
206 CFX_GlyphBitmap* pResult = pGlyphBitmap.get();
208 SizeGlyphCache cache;
209 cache[glyph_index] = std::move(pGlyphBitmap);
211 m_SizeMap[FaceGlyphsKey] = std::move(cache);
215 UniqueKeyGen keygen2(pFont, matrix, dest_width, anti_alias,
217 auto FaceGlyphsKey2 = ByteString(ByteStringView(keygen2.span()));
218 text_options->native_text =
false;
219 return LookUpGlyphBitmap(pFont, matrix, FaceGlyphsKey2, glyph_index,
220 bFontStyle, dest_width, anti_alias);
225 uint32_t glyph_index,
228 const WidthMapKey key = std::make_tuple(glyph_index, dest_width, weight);
229 auto it = m_WidthMap.find(key);
230 if (it != m_WidthMap.end()) {
234 m_WidthMap[key] = font->GetGlyphWidthImpl(glyph_index, dest_width, weight);
235 return m_WidthMap[key];
238#if defined(PDF_USE_SKIA)
243SkFontMgr* g_fontmgr =
nullptr;
247void CFX_GlyphCache::InitializeGlobals() {
250 g_fontmgr = SkFontMgr_New_DirectWrite().release();
251#elif BUILDFLAG(IS_APPLE)
252 g_fontmgr = SkFontMgr_New_CoreText(
nullptr).release();
255 g_fontmgr = SkFontMgr_New_Custom_Empty().release();
260void CFX_GlyphCache::DestroyGlobals() {
266CFX_TypeFace* CFX_GlyphCache::GetDeviceCache(
const CFX_Font* pFont) {
267 if (!m_pTypeface && g_fontmgr) {
268 pdfium::span<
const uint8_t> span = pFont->GetFontSpan();
269 m_pTypeface = g_fontmgr->makeFromStream(
270 std::make_unique<SkMemoryStream>(span.data(), span.size()));
272#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
275 sk_sp<SkFontMgr> freetype_mgr = SkFontMgr_New_Custom_Empty();
276 pdfium::span<
const uint8_t> span = pFont->GetFontSpan();
277 m_pTypeface = freetype_mgr->makeFromStream(
278 std::make_unique<SkMemoryStream>(span.data(), span.size()));
281 return m_pTypeface.get();
289 uint32_t glyph_index,
293 SizeGlyphCache* pSizeCache;
294 auto it = m_SizeMap.find(FaceGlyphsKey);
295 if (it == m_SizeMap.end()) {
296 m_SizeMap[FaceGlyphsKey] = SizeGlyphCache();
297 pSizeCache = &(m_SizeMap[FaceGlyphsKey]);
299 pSizeCache = &(it->second);
302 auto it2 = pSizeCache->find(glyph_index);
303 if (it2 != pSizeCache->end())
304 return it2->second.get();
306 std::unique_ptr<CFX_GlyphBitmap> pGlyphBitmap = RenderGlyph(
307 pFont, glyph_index, bFontStyle, matrix, dest_width, anti_alias);
309 (*pSizeCache)[glyph_index] =
std::move(pGlyphBitmap);
fxcrt::ByteString ByteString
CFX_SubstFont * GetSubstFont() const
const CFX_GlyphBitmap * LoadGlyphBitmap(const CFX_Font *pFont, uint32_t glyph_index, bool bFontStyle, const CFX_Matrix &matrix, int dest_width, int anti_alias, CFX_TextRenderOptions *text_options)
int GetGlyphWidth(const CFX_Font *font, uint32_t glyph_index, int dest_width, int weight)
const CFX_Path * LoadGlyphPath(const CFX_Font *pFont, uint32_t glyph_index, int dest_width)
~CFX_GlyphCache() override
fxcrt::ByteStringView ByteStringView