7#include "core/fxge/cfx_glyphcache.h"
14#include "build/build_config.h"
15#include "core/fxcrt/fx_codepage.h"
16#include "core/fxcrt/fx_memcpy_wrappers.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 "include/ports/SkTypeface_win.h"
31#elif BUILDFLAG(IS_APPLE)
32#include "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);
46 void Generate(
int count, ...);
52void UniqueKeyGen::Generate(
int count, ...) {
54 va_start(argList, count);
55 for (
int i = 0; i < count; i++) {
56 int p = va_arg(argList,
int);
57 reinterpret_cast<uint32_t*>(key_)[i] = p;
60 key_len_ = count *
sizeof(uint32_t);
63void GenKey(UniqueKeyGen* pKeyGen,
69 int nMatrixA =
static_cast<
int>(matrix
.a * 10000);
70 int nMatrixB =
static_cast<
int>(matrix
.b * 10000);
71 int nMatrixC =
static_cast<
int>(matrix
.c * 10000);
72 int nMatrixD =
static_cast<
int>(matrix
.d * 10000);
74#if BUILDFLAG(IS_APPLE)
76 if (pFont->GetSubstFont()) {
77 pKeyGen->Generate(10, nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
78 anti_alias, pFont->GetSubstFont()->m_Weight,
79 pFont->GetSubstFont()->m_ItalicAngle,
80 pFont->IsVertical(), 3);
82 pKeyGen->Generate(7, nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
92 pKeyGen->Generate(9, nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
97 pKeyGen->Generate(6, nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
104CFX_GlyphCache::CFX_GlyphCache(
RetainPtr<CFX_Face> face)
105 : m_Face(std::move(face)) {}
109std::unique_ptr<CFX_GlyphBitmap> CFX_GlyphCache::RenderGlyph(
111 uint32_t glyph_index,
120 return m_Face->RenderGlyph(pFont, glyph_index, bFontStyle, matrix, dest_width,
125 uint32_t glyph_index,
127 if (!GetFace() || glyph_index == kInvalidGlyphIndex) {
132 int weight = pSubstFont ? pSubstFont
->m_Weight : 0;
135 const PathMapKey key =
136 std::make_tuple(glyph_index, dest_width, weight, angle, vertical);
137 auto it = m_PathMap.find(key);
138 if (it != m_PathMap.end())
139 return it->second.get();
141 m_PathMap[key] = pFont->LoadGlyphPathImpl(glyph_index, dest_width);
142 return m_PathMap[key].get();
147 uint32_t glyph_index,
153 if (glyph_index == kInvalidGlyphIndex)
157#if BUILDFLAG(IS_APPLE)
158 const bool bNative = text_options->native_text;
160 const bool bNative =
false;
162 GenKey(&keygen, pFont, matrix, dest_width, anti_alias, bNative);
163 ByteString FaceGlyphsKey(keygen.key_, keygen.key_len_);
165#if BUILDFLAG(IS_APPLE)
166 const bool bDoLookUp =
167 !text_options->native_text || CFX_DefaultRenderDevice::UseSkiaRenderer();
169 const bool bDoLookUp =
true;
172 return LookUpGlyphBitmap(pFont, matrix, FaceGlyphsKey, glyph_index,
173 bFontStyle, dest_width, anti_alias);
176#if BUILDFLAG(IS_APPLE)
177 DCHECK(!CFX_DefaultRenderDevice::UseSkiaRenderer());
179 std::unique_ptr<CFX_GlyphBitmap> pGlyphBitmap;
180 auto it = m_SizeMap.find(FaceGlyphsKey);
181 if (it != m_SizeMap.end()) {
182 SizeGlyphCache* pSizeCache = &(it->second);
183 auto it2 = pSizeCache->find(glyph_index);
184 if (it2 != pSizeCache->end())
185 return it2->second.get();
187 pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, matrix,
188 dest_width, anti_alias);
190 CFX_GlyphBitmap* pResult = pGlyphBitmap.get();
191 (*pSizeCache)[glyph_index] = std::move(pGlyphBitmap);
195 pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, matrix,
196 dest_width, anti_alias);
198 CFX_GlyphBitmap* pResult = pGlyphBitmap.get();
200 SizeGlyphCache cache;
201 cache[glyph_index] = std::move(pGlyphBitmap);
203 m_SizeMap[FaceGlyphsKey] = std::move(cache);
207 GenKey(&keygen, pFont, matrix, dest_width, anti_alias,
false);
208 ByteString FaceGlyphsKey2(keygen.key_, keygen.key_len_);
209 text_options->native_text =
false;
210 return LookUpGlyphBitmap(pFont, matrix, FaceGlyphsKey2, glyph_index,
211 bFontStyle, dest_width, anti_alias);
216 uint32_t glyph_index,
219 const WidthMapKey key = std::make_tuple(glyph_index, dest_width, weight);
220 auto it = m_WidthMap.find(key);
221 if (it != m_WidthMap.end()) {
225 m_WidthMap[key] = font->GetGlyphWidthImpl(glyph_index, dest_width, weight);
226 return m_WidthMap[key];
229#if defined(PDF_USE_SKIA)
234SkFontMgr* g_fontmgr =
nullptr;
238void CFX_GlyphCache::InitializeGlobals() {
241 g_fontmgr = SkFontMgr_New_DirectWrite().release();
242#elif BUILDFLAG(IS_APPLE)
243 g_fontmgr = SkFontMgr_New_CoreText(
nullptr).release();
246 g_fontmgr = SkFontMgr_New_Custom_Empty().release();
251void CFX_GlyphCache::DestroyGlobals() {
257CFX_TypeFace* CFX_GlyphCache::GetDeviceCache(
const CFX_Font* pFont) {
258 if (!m_pTypeface && g_fontmgr) {
259 pdfium::span<
const uint8_t> span = pFont->GetFontSpan();
260 m_pTypeface = g_fontmgr->makeFromStream(
261 std::make_unique<SkMemoryStream>(span.data(), span.size()));
263#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
266 sk_sp<SkFontMgr> freetype_mgr = SkFontMgr_New_Custom_Empty();
267 pdfium::span<
const uint8_t> span = pFont->GetFontSpan();
268 m_pTypeface = freetype_mgr->makeFromStream(
269 std::make_unique<SkMemoryStream>(span.data(), span.size()));
272 return m_pTypeface.get();
279 const ByteString& FaceGlyphsKey,
280 uint32_t glyph_index,
284 SizeGlyphCache* pSizeCache;
285 auto it = m_SizeMap.find(FaceGlyphsKey);
286 if (it == m_SizeMap.end()) {
287 m_SizeMap[FaceGlyphsKey] = SizeGlyphCache();
288 pSizeCache = &(m_SizeMap[FaceGlyphsKey]);
290 pSizeCache = &(it->second);
293 auto it2 = pSizeCache->find(glyph_index);
294 if (it2 != pSizeCache->end())
295 return it2->second.get();
297 std::unique_ptr<CFX_GlyphBitmap> pGlyphBitmap = RenderGlyph(
298 pFont, glyph_index, bFontStyle, matrix, dest_width, anti_alias);
300 (*pSizeCache)[glyph_index] =
std::move(pGlyphBitmap);
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