1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2015 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fgas/font/cfgas_fontmgr.h"
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include <stdint.h>
10*3ac0a46fSAndroid Build Coastguard Worker
11*3ac0a46fSAndroid Build Coastguard Worker #include <algorithm>
12*3ac0a46fSAndroid Build Coastguard Worker #include <iterator>
13*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
14*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
15*3ac0a46fSAndroid Build Coastguard Worker
16*3ac0a46fSAndroid Build Coastguard Worker #include "build/build_config.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/cfx_read_only_vector_stream.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/data_vector.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fixed_uninit_data_vector.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_codepage.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_extension.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_memory_wrappers.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_system.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_font.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_fontmapper.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_fontmgr.h"
27*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_gemodule.h"
28*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/fx_font.h"
29*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
30*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/containers/contains.h"
31*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/containers/span.h"
32*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/numerics/safe_conversions.h"
33*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fgas/font/cfgas_gefont.h"
34*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fgas/font/fgas_fontutils.h"
35*3ac0a46fSAndroid Build Coastguard Worker
36*3ac0a46fSAndroid Build Coastguard Worker namespace {
37*3ac0a46fSAndroid Build Coastguard Worker
VerifyUnicode(const RetainPtr<CFGAS_GEFont> & pFont,wchar_t wcUnicode)38*3ac0a46fSAndroid Build Coastguard Worker bool VerifyUnicode(const RetainPtr<CFGAS_GEFont>& pFont, wchar_t wcUnicode) {
39*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFX_Face> pFace = pFont->GetDevFont()->GetFace();
40*3ac0a46fSAndroid Build Coastguard Worker if (!pFace)
41*3ac0a46fSAndroid Build Coastguard Worker return false;
42*3ac0a46fSAndroid Build Coastguard Worker
43*3ac0a46fSAndroid Build Coastguard Worker FXFT_FaceRec* pFaceRec = pFace->GetRec();
44*3ac0a46fSAndroid Build Coastguard Worker FT_CharMap charmap = pFaceRec->charmap;
45*3ac0a46fSAndroid Build Coastguard Worker if (FXFT_Select_Charmap(pFaceRec, FT_ENCODING_UNICODE) != 0)
46*3ac0a46fSAndroid Build Coastguard Worker return false;
47*3ac0a46fSAndroid Build Coastguard Worker
48*3ac0a46fSAndroid Build Coastguard Worker if (FT_Get_Char_Index(pFaceRec, wcUnicode) == 0) {
49*3ac0a46fSAndroid Build Coastguard Worker FT_Set_Charmap(pFaceRec, charmap);
50*3ac0a46fSAndroid Build Coastguard Worker return false;
51*3ac0a46fSAndroid Build Coastguard Worker }
52*3ac0a46fSAndroid Build Coastguard Worker return true;
53*3ac0a46fSAndroid Build Coastguard Worker }
54*3ac0a46fSAndroid Build Coastguard Worker
ShortFormHash(FX_CodePage wCodePage,uint32_t dwFontStyles,WideStringView wsFontFamily)55*3ac0a46fSAndroid Build Coastguard Worker uint32_t ShortFormHash(FX_CodePage wCodePage,
56*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles,
57*3ac0a46fSAndroid Build Coastguard Worker WideStringView wsFontFamily) {
58*3ac0a46fSAndroid Build Coastguard Worker ByteString bsHash = ByteString::Format("%d, %d", wCodePage, dwFontStyles);
59*3ac0a46fSAndroid Build Coastguard Worker bsHash += FX_UTF8Encode(wsFontFamily);
60*3ac0a46fSAndroid Build Coastguard Worker return FX_HashCode_GetA(bsHash.AsStringView());
61*3ac0a46fSAndroid Build Coastguard Worker }
62*3ac0a46fSAndroid Build Coastguard Worker
LongFormHash(FX_CodePage wCodePage,uint16_t wBitField,uint32_t dwFontStyles,WideStringView wsFontFamily)63*3ac0a46fSAndroid Build Coastguard Worker uint32_t LongFormHash(FX_CodePage wCodePage,
64*3ac0a46fSAndroid Build Coastguard Worker uint16_t wBitField,
65*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles,
66*3ac0a46fSAndroid Build Coastguard Worker WideStringView wsFontFamily) {
67*3ac0a46fSAndroid Build Coastguard Worker ByteString bsHash =
68*3ac0a46fSAndroid Build Coastguard Worker ByteString::Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles);
69*3ac0a46fSAndroid Build Coastguard Worker bsHash += FX_UTF8Encode(wsFontFamily);
70*3ac0a46fSAndroid Build Coastguard Worker return FX_HashCode_GetA(bsHash.AsStringView());
71*3ac0a46fSAndroid Build Coastguard Worker }
72*3ac0a46fSAndroid Build Coastguard Worker
73*3ac0a46fSAndroid Build Coastguard Worker } // namespace
74*3ac0a46fSAndroid Build Coastguard Worker
75*3ac0a46fSAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
76*3ac0a46fSAndroid Build Coastguard Worker
77*3ac0a46fSAndroid Build Coastguard Worker namespace {
78*3ac0a46fSAndroid Build Coastguard Worker
79*3ac0a46fSAndroid Build Coastguard Worker struct FX_FONTMATCHPARAMS {
80*3ac0a46fSAndroid Build Coastguard Worker const wchar_t* pwsFamily;
81*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles;
82*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwUSB;
83*3ac0a46fSAndroid Build Coastguard Worker bool matchParagraphStyle;
84*3ac0a46fSAndroid Build Coastguard Worker wchar_t wUnicode;
85*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage wCodePage;
86*3ac0a46fSAndroid Build Coastguard Worker };
87*3ac0a46fSAndroid Build Coastguard Worker
GetSimilarityScore(FX_FONTDESCRIPTOR const * pFont,uint32_t dwFontStyles)88*3ac0a46fSAndroid Build Coastguard Worker int32_t GetSimilarityScore(FX_FONTDESCRIPTOR const* pFont,
89*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles) {
90*3ac0a46fSAndroid Build Coastguard Worker int32_t iValue = 0;
91*3ac0a46fSAndroid Build Coastguard Worker if (FontStyleIsSymbolic(dwFontStyles) ==
92*3ac0a46fSAndroid Build Coastguard Worker FontStyleIsSymbolic(pFont->dwFontStyles)) {
93*3ac0a46fSAndroid Build Coastguard Worker iValue += 64;
94*3ac0a46fSAndroid Build Coastguard Worker }
95*3ac0a46fSAndroid Build Coastguard Worker if (FontStyleIsFixedPitch(dwFontStyles) ==
96*3ac0a46fSAndroid Build Coastguard Worker FontStyleIsFixedPitch(pFont->dwFontStyles)) {
97*3ac0a46fSAndroid Build Coastguard Worker iValue += 32;
98*3ac0a46fSAndroid Build Coastguard Worker }
99*3ac0a46fSAndroid Build Coastguard Worker if (FontStyleIsSerif(dwFontStyles) == FontStyleIsSerif(pFont->dwFontStyles))
100*3ac0a46fSAndroid Build Coastguard Worker iValue += 16;
101*3ac0a46fSAndroid Build Coastguard Worker if (FontStyleIsScript(dwFontStyles) == FontStyleIsScript(pFont->dwFontStyles))
102*3ac0a46fSAndroid Build Coastguard Worker iValue += 8;
103*3ac0a46fSAndroid Build Coastguard Worker return iValue;
104*3ac0a46fSAndroid Build Coastguard Worker }
105*3ac0a46fSAndroid Build Coastguard Worker
MatchDefaultFont(FX_FONTMATCHPARAMS * pParams,const std::deque<FX_FONTDESCRIPTOR> & fonts)106*3ac0a46fSAndroid Build Coastguard Worker const FX_FONTDESCRIPTOR* MatchDefaultFont(
107*3ac0a46fSAndroid Build Coastguard Worker FX_FONTMATCHPARAMS* pParams,
108*3ac0a46fSAndroid Build Coastguard Worker const std::deque<FX_FONTDESCRIPTOR>& fonts) {
109*3ac0a46fSAndroid Build Coastguard Worker const FX_FONTDESCRIPTOR* pBestFont = nullptr;
110*3ac0a46fSAndroid Build Coastguard Worker int32_t iBestSimilar = 0;
111*3ac0a46fSAndroid Build Coastguard Worker for (const auto& font : fonts) {
112*3ac0a46fSAndroid Build Coastguard Worker if (FontStyleIsForceBold(font.dwFontStyles) &&
113*3ac0a46fSAndroid Build Coastguard Worker FontStyleIsItalic(font.dwFontStyles)) {
114*3ac0a46fSAndroid Build Coastguard Worker continue;
115*3ac0a46fSAndroid Build Coastguard Worker }
116*3ac0a46fSAndroid Build Coastguard Worker
117*3ac0a46fSAndroid Build Coastguard Worker if (pParams->pwsFamily) {
118*3ac0a46fSAndroid Build Coastguard Worker if (FXSYS_wcsicmp(pParams->pwsFamily, font.wsFontFace))
119*3ac0a46fSAndroid Build Coastguard Worker continue;
120*3ac0a46fSAndroid Build Coastguard Worker if (font.uCharSet == FX_Charset::kSymbol)
121*3ac0a46fSAndroid Build Coastguard Worker return &font;
122*3ac0a46fSAndroid Build Coastguard Worker }
123*3ac0a46fSAndroid Build Coastguard Worker if (font.uCharSet == FX_Charset::kSymbol)
124*3ac0a46fSAndroid Build Coastguard Worker continue;
125*3ac0a46fSAndroid Build Coastguard Worker if (pParams->wCodePage != FX_CodePage::kFailure) {
126*3ac0a46fSAndroid Build Coastguard Worker if (FX_GetCodePageFromCharset(font.uCharSet) != pParams->wCodePage)
127*3ac0a46fSAndroid Build Coastguard Worker continue;
128*3ac0a46fSAndroid Build Coastguard Worker } else {
129*3ac0a46fSAndroid Build Coastguard Worker if (pParams->dwUSB < 128) {
130*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwByte = pParams->dwUSB / 32;
131*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwUSB = 1 << (pParams->dwUSB % 32);
132*3ac0a46fSAndroid Build Coastguard Worker if ((font.FontSignature.fsUsb[dwByte] & dwUSB) == 0)
133*3ac0a46fSAndroid Build Coastguard Worker continue;
134*3ac0a46fSAndroid Build Coastguard Worker }
135*3ac0a46fSAndroid Build Coastguard Worker }
136*3ac0a46fSAndroid Build Coastguard Worker if (pParams->matchParagraphStyle) {
137*3ac0a46fSAndroid Build Coastguard Worker if ((font.dwFontStyles & 0x0F) == (pParams->dwFontStyles & 0x0F))
138*3ac0a46fSAndroid Build Coastguard Worker return &font;
139*3ac0a46fSAndroid Build Coastguard Worker continue;
140*3ac0a46fSAndroid Build Coastguard Worker }
141*3ac0a46fSAndroid Build Coastguard Worker if (pParams->pwsFamily) {
142*3ac0a46fSAndroid Build Coastguard Worker if (FXSYS_wcsicmp(pParams->pwsFamily, font.wsFontFace) == 0)
143*3ac0a46fSAndroid Build Coastguard Worker return &font;
144*3ac0a46fSAndroid Build Coastguard Worker }
145*3ac0a46fSAndroid Build Coastguard Worker int32_t iSimilarValue = GetSimilarityScore(&font, pParams->dwFontStyles);
146*3ac0a46fSAndroid Build Coastguard Worker if (iBestSimilar < iSimilarValue) {
147*3ac0a46fSAndroid Build Coastguard Worker iBestSimilar = iSimilarValue;
148*3ac0a46fSAndroid Build Coastguard Worker pBestFont = &font;
149*3ac0a46fSAndroid Build Coastguard Worker }
150*3ac0a46fSAndroid Build Coastguard Worker }
151*3ac0a46fSAndroid Build Coastguard Worker return iBestSimilar < 1 ? nullptr : pBestFont;
152*3ac0a46fSAndroid Build Coastguard Worker }
153*3ac0a46fSAndroid Build Coastguard Worker
GetGdiFontStyles(const LOGFONTW & lf)154*3ac0a46fSAndroid Build Coastguard Worker uint32_t GetGdiFontStyles(const LOGFONTW& lf) {
155*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwStyles = 0;
156*3ac0a46fSAndroid Build Coastguard Worker if ((lf.lfPitchAndFamily & 0x03) == FIXED_PITCH)
157*3ac0a46fSAndroid Build Coastguard Worker dwStyles |= FXFONT_FIXED_PITCH;
158*3ac0a46fSAndroid Build Coastguard Worker uint8_t nFamilies = lf.lfPitchAndFamily & 0xF0;
159*3ac0a46fSAndroid Build Coastguard Worker if (nFamilies == FF_ROMAN)
160*3ac0a46fSAndroid Build Coastguard Worker dwStyles |= FXFONT_SERIF;
161*3ac0a46fSAndroid Build Coastguard Worker if (nFamilies == FF_SCRIPT)
162*3ac0a46fSAndroid Build Coastguard Worker dwStyles |= FXFONT_SCRIPT;
163*3ac0a46fSAndroid Build Coastguard Worker if (lf.lfCharSet == SYMBOL_CHARSET)
164*3ac0a46fSAndroid Build Coastguard Worker dwStyles |= FXFONT_SYMBOLIC;
165*3ac0a46fSAndroid Build Coastguard Worker return dwStyles;
166*3ac0a46fSAndroid Build Coastguard Worker }
167*3ac0a46fSAndroid Build Coastguard Worker
GdiFontEnumProc(ENUMLOGFONTEX * lpelfe,NEWTEXTMETRICEX * lpntme,DWORD dwFontType,LPARAM lParam)168*3ac0a46fSAndroid Build Coastguard Worker int32_t CALLBACK GdiFontEnumProc(ENUMLOGFONTEX* lpelfe,
169*3ac0a46fSAndroid Build Coastguard Worker NEWTEXTMETRICEX* lpntme,
170*3ac0a46fSAndroid Build Coastguard Worker DWORD dwFontType,
171*3ac0a46fSAndroid Build Coastguard Worker LPARAM lParam) {
172*3ac0a46fSAndroid Build Coastguard Worker if (dwFontType != TRUETYPE_FONTTYPE)
173*3ac0a46fSAndroid Build Coastguard Worker return 1;
174*3ac0a46fSAndroid Build Coastguard Worker const LOGFONTW& lf = ((LPENUMLOGFONTEXW)lpelfe)->elfLogFont;
175*3ac0a46fSAndroid Build Coastguard Worker if (lf.lfFaceName[0] == L'@')
176*3ac0a46fSAndroid Build Coastguard Worker return 1;
177*3ac0a46fSAndroid Build Coastguard Worker FX_FONTDESCRIPTOR font;
178*3ac0a46fSAndroid Build Coastguard Worker memset(&font, 0, sizeof(FX_FONTDESCRIPTOR));
179*3ac0a46fSAndroid Build Coastguard Worker font.uCharSet = FX_GetCharsetFromInt(lf.lfCharSet);
180*3ac0a46fSAndroid Build Coastguard Worker font.dwFontStyles = GetGdiFontStyles(lf);
181*3ac0a46fSAndroid Build Coastguard Worker FXSYS_wcsncpy(font.wsFontFace, (const wchar_t*)lf.lfFaceName, 31);
182*3ac0a46fSAndroid Build Coastguard Worker font.wsFontFace[31] = 0;
183*3ac0a46fSAndroid Build Coastguard Worker memcpy(&font.FontSignature, &lpntme->ntmFontSig, sizeof(lpntme->ntmFontSig));
184*3ac0a46fSAndroid Build Coastguard Worker reinterpret_cast<std::deque<FX_FONTDESCRIPTOR>*>(lParam)->push_back(font);
185*3ac0a46fSAndroid Build Coastguard Worker return 1;
186*3ac0a46fSAndroid Build Coastguard Worker }
187*3ac0a46fSAndroid Build Coastguard Worker
EnumGdiFonts(const wchar_t * pwsFaceName,wchar_t wUnicode)188*3ac0a46fSAndroid Build Coastguard Worker std::deque<FX_FONTDESCRIPTOR> EnumGdiFonts(const wchar_t* pwsFaceName,
189*3ac0a46fSAndroid Build Coastguard Worker wchar_t wUnicode) {
190*3ac0a46fSAndroid Build Coastguard Worker std::deque<FX_FONTDESCRIPTOR> fonts;
191*3ac0a46fSAndroid Build Coastguard Worker LOGFONTW lfFind;
192*3ac0a46fSAndroid Build Coastguard Worker memset(&lfFind, 0, sizeof(lfFind));
193*3ac0a46fSAndroid Build Coastguard Worker lfFind.lfCharSet = DEFAULT_CHARSET;
194*3ac0a46fSAndroid Build Coastguard Worker if (pwsFaceName) {
195*3ac0a46fSAndroid Build Coastguard Worker FXSYS_wcsncpy(lfFind.lfFaceName, pwsFaceName, 31);
196*3ac0a46fSAndroid Build Coastguard Worker lfFind.lfFaceName[31] = 0;
197*3ac0a46fSAndroid Build Coastguard Worker }
198*3ac0a46fSAndroid Build Coastguard Worker HDC hDC = ::GetDC(nullptr);
199*3ac0a46fSAndroid Build Coastguard Worker EnumFontFamiliesExW(hDC, (LPLOGFONTW)&lfFind, (FONTENUMPROCW)GdiFontEnumProc,
200*3ac0a46fSAndroid Build Coastguard Worker (LPARAM)&fonts, 0);
201*3ac0a46fSAndroid Build Coastguard Worker ::ReleaseDC(nullptr, hDC);
202*3ac0a46fSAndroid Build Coastguard Worker return fonts;
203*3ac0a46fSAndroid Build Coastguard Worker }
204*3ac0a46fSAndroid Build Coastguard Worker
205*3ac0a46fSAndroid Build Coastguard Worker } // namespace
206*3ac0a46fSAndroid Build Coastguard Worker
CFGAS_FontMgr()207*3ac0a46fSAndroid Build Coastguard Worker CFGAS_FontMgr::CFGAS_FontMgr() : m_FontFaces(EnumGdiFonts(nullptr, 0xFEFF)) {}
208*3ac0a46fSAndroid Build Coastguard Worker
209*3ac0a46fSAndroid Build Coastguard Worker CFGAS_FontMgr::~CFGAS_FontMgr() = default;
210*3ac0a46fSAndroid Build Coastguard Worker
EnumFonts()211*3ac0a46fSAndroid Build Coastguard Worker bool CFGAS_FontMgr::EnumFonts() {
212*3ac0a46fSAndroid Build Coastguard Worker return true;
213*3ac0a46fSAndroid Build Coastguard Worker }
214*3ac0a46fSAndroid Build Coastguard Worker
GetFontByUnicodeImpl(wchar_t wUnicode,uint32_t dwFontStyles,const wchar_t * pszFontFamily,uint32_t dwHash,FX_CodePage wCodePage,uint16_t wBitField)215*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicodeImpl(
216*3ac0a46fSAndroid Build Coastguard Worker wchar_t wUnicode,
217*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles,
218*3ac0a46fSAndroid Build Coastguard Worker const wchar_t* pszFontFamily,
219*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwHash,
220*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage wCodePage,
221*3ac0a46fSAndroid Build Coastguard Worker uint16_t wBitField) {
222*3ac0a46fSAndroid Build Coastguard Worker const FX_FONTDESCRIPTOR* pFD = FindFont(pszFontFamily, dwFontStyles, false,
223*3ac0a46fSAndroid Build Coastguard Worker wCodePage, wBitField, wUnicode);
224*3ac0a46fSAndroid Build Coastguard Worker if (!pFD && pszFontFamily) {
225*3ac0a46fSAndroid Build Coastguard Worker pFD =
226*3ac0a46fSAndroid Build Coastguard Worker FindFont(nullptr, dwFontStyles, false, wCodePage, wBitField, wUnicode);
227*3ac0a46fSAndroid Build Coastguard Worker }
228*3ac0a46fSAndroid Build Coastguard Worker if (!pFD)
229*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
230*3ac0a46fSAndroid Build Coastguard Worker
231*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage newCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
232*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFGAS_GEFont> pFont =
233*3ac0a46fSAndroid Build Coastguard Worker CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, newCodePage);
234*3ac0a46fSAndroid Build Coastguard Worker if (!pFont)
235*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
236*3ac0a46fSAndroid Build Coastguard Worker
237*3ac0a46fSAndroid Build Coastguard Worker pFont->SetLogicalFontStyle(dwFontStyles);
238*3ac0a46fSAndroid Build Coastguard Worker if (!VerifyUnicode(pFont, wUnicode)) {
239*3ac0a46fSAndroid Build Coastguard Worker m_FailedUnicodesSet.insert(wUnicode);
240*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
241*3ac0a46fSAndroid Build Coastguard Worker }
242*3ac0a46fSAndroid Build Coastguard Worker
243*3ac0a46fSAndroid Build Coastguard Worker m_Hash2Fonts[dwHash].push_back(pFont);
244*3ac0a46fSAndroid Build Coastguard Worker return pFont;
245*3ac0a46fSAndroid Build Coastguard Worker }
246*3ac0a46fSAndroid Build Coastguard Worker
FindFont(const wchar_t * pszFontFamily,uint32_t dwFontStyles,bool matchParagraphStyle,FX_CodePage wCodePage,uint32_t dwUSB,wchar_t wUnicode)247*3ac0a46fSAndroid Build Coastguard Worker const FX_FONTDESCRIPTOR* CFGAS_FontMgr::FindFont(const wchar_t* pszFontFamily,
248*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles,
249*3ac0a46fSAndroid Build Coastguard Worker bool matchParagraphStyle,
250*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage wCodePage,
251*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwUSB,
252*3ac0a46fSAndroid Build Coastguard Worker wchar_t wUnicode) {
253*3ac0a46fSAndroid Build Coastguard Worker FX_FONTMATCHPARAMS params;
254*3ac0a46fSAndroid Build Coastguard Worker memset(¶ms, 0, sizeof(params));
255*3ac0a46fSAndroid Build Coastguard Worker params.dwUSB = dwUSB;
256*3ac0a46fSAndroid Build Coastguard Worker params.wUnicode = wUnicode;
257*3ac0a46fSAndroid Build Coastguard Worker params.wCodePage = wCodePage;
258*3ac0a46fSAndroid Build Coastguard Worker params.pwsFamily = pszFontFamily;
259*3ac0a46fSAndroid Build Coastguard Worker params.dwFontStyles = dwFontStyles;
260*3ac0a46fSAndroid Build Coastguard Worker params.matchParagraphStyle = matchParagraphStyle;
261*3ac0a46fSAndroid Build Coastguard Worker
262*3ac0a46fSAndroid Build Coastguard Worker const FX_FONTDESCRIPTOR* pDesc = MatchDefaultFont(¶ms, m_FontFaces);
263*3ac0a46fSAndroid Build Coastguard Worker if (pDesc)
264*3ac0a46fSAndroid Build Coastguard Worker return pDesc;
265*3ac0a46fSAndroid Build Coastguard Worker
266*3ac0a46fSAndroid Build Coastguard Worker if (!pszFontFamily)
267*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
268*3ac0a46fSAndroid Build Coastguard Worker
269*3ac0a46fSAndroid Build Coastguard Worker // Use a named object to store the returned value of EnumGdiFonts() instead
270*3ac0a46fSAndroid Build Coastguard Worker // of using a temporary object. This can prevent use-after-free issues since
271*3ac0a46fSAndroid Build Coastguard Worker // pDesc may point to one of std::deque object's elements.
272*3ac0a46fSAndroid Build Coastguard Worker std::deque<FX_FONTDESCRIPTOR> namedFonts =
273*3ac0a46fSAndroid Build Coastguard Worker EnumGdiFonts(pszFontFamily, wUnicode);
274*3ac0a46fSAndroid Build Coastguard Worker params.pwsFamily = nullptr;
275*3ac0a46fSAndroid Build Coastguard Worker pDesc = MatchDefaultFont(¶ms, namedFonts);
276*3ac0a46fSAndroid Build Coastguard Worker if (!pDesc)
277*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
278*3ac0a46fSAndroid Build Coastguard Worker
279*3ac0a46fSAndroid Build Coastguard Worker auto it = std::find(m_FontFaces.rbegin(), m_FontFaces.rend(), *pDesc);
280*3ac0a46fSAndroid Build Coastguard Worker if (it != m_FontFaces.rend())
281*3ac0a46fSAndroid Build Coastguard Worker return &*it;
282*3ac0a46fSAndroid Build Coastguard Worker
283*3ac0a46fSAndroid Build Coastguard Worker m_FontFaces.push_back(*pDesc);
284*3ac0a46fSAndroid Build Coastguard Worker return &m_FontFaces.back();
285*3ac0a46fSAndroid Build Coastguard Worker }
286*3ac0a46fSAndroid Build Coastguard Worker
287*3ac0a46fSAndroid Build Coastguard Worker #else // BUILDFLAG(IS_WIN)
288*3ac0a46fSAndroid Build Coastguard Worker
289*3ac0a46fSAndroid Build Coastguard Worker namespace {
290*3ac0a46fSAndroid Build Coastguard Worker
291*3ac0a46fSAndroid Build Coastguard Worker const FX_CodePage kCodePages[] = {FX_CodePage::kMSWin_WesternEuropean,
292*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSWin_EasternEuropean,
293*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSWin_Cyrillic,
294*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSWin_Greek,
295*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSWin_Turkish,
296*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSWin_Hebrew,
297*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSWin_Arabic,
298*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSWin_Baltic,
299*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSWin_Vietnamese,
300*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
301*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
302*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
303*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
304*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
305*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
306*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
307*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Thai,
308*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kShiftJIS,
309*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kChineseSimplified,
310*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kHangul,
311*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kChineseTraditional,
312*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kJohab,
313*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
314*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
315*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
316*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
317*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
318*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
319*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
320*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
321*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
322*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
323*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
324*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
325*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
326*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
327*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
328*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
329*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
330*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
331*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
332*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
333*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
334*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
335*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
336*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
337*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
338*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kDefANSI,
339*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Greek2,
340*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Russian,
341*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Norwegian,
342*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Arabic,
343*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_FrenchCanadian,
344*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Hebrew,
345*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Icelandic,
346*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Portuguese,
347*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Turkish,
348*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Cyrillic,
349*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_EasternEuropean,
350*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Baltic,
351*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_Greek1,
352*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kArabic_ASMO708,
353*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_WesternEuropean,
354*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage::kMSDOS_US};
355*3ac0a46fSAndroid Build Coastguard Worker
FX_GetCodePageBit(FX_CodePage wCodePage)356*3ac0a46fSAndroid Build Coastguard Worker uint16_t FX_GetCodePageBit(FX_CodePage wCodePage) {
357*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 0; i < std::size(kCodePages); ++i) {
358*3ac0a46fSAndroid Build Coastguard Worker if (kCodePages[i] == wCodePage)
359*3ac0a46fSAndroid Build Coastguard Worker return static_cast<uint16_t>(i);
360*3ac0a46fSAndroid Build Coastguard Worker }
361*3ac0a46fSAndroid Build Coastguard Worker return static_cast<uint16_t>(-1);
362*3ac0a46fSAndroid Build Coastguard Worker }
363*3ac0a46fSAndroid Build Coastguard Worker
FX_GetUnicodeBit(wchar_t wcUnicode)364*3ac0a46fSAndroid Build Coastguard Worker uint16_t FX_GetUnicodeBit(wchar_t wcUnicode) {
365*3ac0a46fSAndroid Build Coastguard Worker const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wcUnicode);
366*3ac0a46fSAndroid Build Coastguard Worker return x ? x->wBitField : FGAS_FONTUSB::kNoBitField;
367*3ac0a46fSAndroid Build Coastguard Worker }
368*3ac0a46fSAndroid Build Coastguard Worker
ReadUInt16FromSpanAtOffset(pdfium::span<const uint8_t> data,size_t offset)369*3ac0a46fSAndroid Build Coastguard Worker uint16_t ReadUInt16FromSpanAtOffset(pdfium::span<const uint8_t> data,
370*3ac0a46fSAndroid Build Coastguard Worker size_t offset) {
371*3ac0a46fSAndroid Build Coastguard Worker const uint8_t* p = &data[offset];
372*3ac0a46fSAndroid Build Coastguard Worker return FXSYS_UINT16_GET_MSBFIRST(p);
373*3ac0a46fSAndroid Build Coastguard Worker }
374*3ac0a46fSAndroid Build Coastguard Worker
375*3ac0a46fSAndroid Build Coastguard Worker extern "C" {
376*3ac0a46fSAndroid Build Coastguard Worker
ftStreamRead(FXFT_StreamRec * stream,unsigned long offset,unsigned char * buffer,unsigned long count)377*3ac0a46fSAndroid Build Coastguard Worker unsigned long ftStreamRead(FXFT_StreamRec* stream,
378*3ac0a46fSAndroid Build Coastguard Worker unsigned long offset,
379*3ac0a46fSAndroid Build Coastguard Worker unsigned char* buffer,
380*3ac0a46fSAndroid Build Coastguard Worker unsigned long count) {
381*3ac0a46fSAndroid Build Coastguard Worker if (count == 0)
382*3ac0a46fSAndroid Build Coastguard Worker return 0;
383*3ac0a46fSAndroid Build Coastguard Worker
384*3ac0a46fSAndroid Build Coastguard Worker IFX_SeekableReadStream* pFile =
385*3ac0a46fSAndroid Build Coastguard Worker static_cast<IFX_SeekableReadStream*>(stream->descriptor.pointer);
386*3ac0a46fSAndroid Build Coastguard Worker if (!pFile->ReadBlockAtOffset({buffer, count}, offset))
387*3ac0a46fSAndroid Build Coastguard Worker return 0;
388*3ac0a46fSAndroid Build Coastguard Worker
389*3ac0a46fSAndroid Build Coastguard Worker return count;
390*3ac0a46fSAndroid Build Coastguard Worker }
391*3ac0a46fSAndroid Build Coastguard Worker
ftStreamClose(FXFT_StreamRec * stream)392*3ac0a46fSAndroid Build Coastguard Worker void ftStreamClose(FXFT_StreamRec* stream) {}
393*3ac0a46fSAndroid Build Coastguard Worker
394*3ac0a46fSAndroid Build Coastguard Worker } // extern "C"
395*3ac0a46fSAndroid Build Coastguard Worker
GetNames(pdfium::span<const uint8_t> name_table)396*3ac0a46fSAndroid Build Coastguard Worker std::vector<WideString> GetNames(pdfium::span<const uint8_t> name_table) {
397*3ac0a46fSAndroid Build Coastguard Worker std::vector<WideString> results;
398*3ac0a46fSAndroid Build Coastguard Worker if (name_table.empty())
399*3ac0a46fSAndroid Build Coastguard Worker return results;
400*3ac0a46fSAndroid Build Coastguard Worker
401*3ac0a46fSAndroid Build Coastguard Worker uint16_t nNameCount = ReadUInt16FromSpanAtOffset(name_table, 2);
402*3ac0a46fSAndroid Build Coastguard Worker pdfium::span<const uint8_t> str =
403*3ac0a46fSAndroid Build Coastguard Worker name_table.subspan(ReadUInt16FromSpanAtOffset(name_table, 4));
404*3ac0a46fSAndroid Build Coastguard Worker pdfium::span<const uint8_t> name_record = name_table.subspan(6);
405*3ac0a46fSAndroid Build Coastguard Worker for (uint16_t i = 0; i < nNameCount; ++i) {
406*3ac0a46fSAndroid Build Coastguard Worker uint16_t nNameID = ReadUInt16FromSpanAtOffset(name_table, i * 12 + 6);
407*3ac0a46fSAndroid Build Coastguard Worker if (nNameID != 1)
408*3ac0a46fSAndroid Build Coastguard Worker continue;
409*3ac0a46fSAndroid Build Coastguard Worker
410*3ac0a46fSAndroid Build Coastguard Worker uint16_t nPlatformID = ReadUInt16FromSpanAtOffset(name_record, i * 12);
411*3ac0a46fSAndroid Build Coastguard Worker uint16_t nNameLength = ReadUInt16FromSpanAtOffset(name_record, i * 12 + 8);
412*3ac0a46fSAndroid Build Coastguard Worker uint16_t nNameOffset = ReadUInt16FromSpanAtOffset(name_record, i * 12 + 10);
413*3ac0a46fSAndroid Build Coastguard Worker if (nPlatformID != 1) {
414*3ac0a46fSAndroid Build Coastguard Worker WideString wsFamily;
415*3ac0a46fSAndroid Build Coastguard Worker for (uint16_t j = 0; j < nNameLength / 2; ++j) {
416*3ac0a46fSAndroid Build Coastguard Worker wchar_t wcTemp = ReadUInt16FromSpanAtOffset(str, nNameOffset + j * 2);
417*3ac0a46fSAndroid Build Coastguard Worker wsFamily += wcTemp;
418*3ac0a46fSAndroid Build Coastguard Worker }
419*3ac0a46fSAndroid Build Coastguard Worker results.push_back(wsFamily);
420*3ac0a46fSAndroid Build Coastguard Worker continue;
421*3ac0a46fSAndroid Build Coastguard Worker }
422*3ac0a46fSAndroid Build Coastguard Worker
423*3ac0a46fSAndroid Build Coastguard Worker WideString wsFamily;
424*3ac0a46fSAndroid Build Coastguard Worker for (uint16_t j = 0; j < nNameLength; ++j) {
425*3ac0a46fSAndroid Build Coastguard Worker wchar_t wcTemp = str[nNameOffset + j];
426*3ac0a46fSAndroid Build Coastguard Worker wsFamily += wcTemp;
427*3ac0a46fSAndroid Build Coastguard Worker }
428*3ac0a46fSAndroid Build Coastguard Worker results.push_back(wsFamily);
429*3ac0a46fSAndroid Build Coastguard Worker }
430*3ac0a46fSAndroid Build Coastguard Worker return results;
431*3ac0a46fSAndroid Build Coastguard Worker }
432*3ac0a46fSAndroid Build Coastguard Worker
GetUSBCSB(FXFT_FaceRec * pFace,uint32_t * USB,uint32_t * CSB)433*3ac0a46fSAndroid Build Coastguard Worker void GetUSBCSB(FXFT_FaceRec* pFace, uint32_t* USB, uint32_t* CSB) {
434*3ac0a46fSAndroid Build Coastguard Worker TT_OS2* pOS2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(pFace, ft_sfnt_os2));
435*3ac0a46fSAndroid Build Coastguard Worker if (!pOS2) {
436*3ac0a46fSAndroid Build Coastguard Worker USB[0] = 0;
437*3ac0a46fSAndroid Build Coastguard Worker USB[1] = 0;
438*3ac0a46fSAndroid Build Coastguard Worker USB[2] = 0;
439*3ac0a46fSAndroid Build Coastguard Worker USB[3] = 0;
440*3ac0a46fSAndroid Build Coastguard Worker CSB[0] = 0;
441*3ac0a46fSAndroid Build Coastguard Worker CSB[1] = 0;
442*3ac0a46fSAndroid Build Coastguard Worker return;
443*3ac0a46fSAndroid Build Coastguard Worker }
444*3ac0a46fSAndroid Build Coastguard Worker USB[0] = static_cast<uint32_t>(pOS2->ulUnicodeRange1);
445*3ac0a46fSAndroid Build Coastguard Worker USB[1] = static_cast<uint32_t>(pOS2->ulUnicodeRange2);
446*3ac0a46fSAndroid Build Coastguard Worker USB[2] = static_cast<uint32_t>(pOS2->ulUnicodeRange3);
447*3ac0a46fSAndroid Build Coastguard Worker USB[3] = static_cast<uint32_t>(pOS2->ulUnicodeRange4);
448*3ac0a46fSAndroid Build Coastguard Worker CSB[0] = static_cast<uint32_t>(pOS2->ulCodePageRange1);
449*3ac0a46fSAndroid Build Coastguard Worker CSB[1] = static_cast<uint32_t>(pOS2->ulCodePageRange2);
450*3ac0a46fSAndroid Build Coastguard Worker }
451*3ac0a46fSAndroid Build Coastguard Worker
GetFlags(FXFT_FaceRec * pFace)452*3ac0a46fSAndroid Build Coastguard Worker uint32_t GetFlags(FXFT_FaceRec* pFace) {
453*3ac0a46fSAndroid Build Coastguard Worker uint32_t flags = 0;
454*3ac0a46fSAndroid Build Coastguard Worker if (FXFT_Is_Face_Bold(pFace))
455*3ac0a46fSAndroid Build Coastguard Worker flags |= FXFONT_FORCE_BOLD;
456*3ac0a46fSAndroid Build Coastguard Worker if (FXFT_Is_Face_Italic(pFace))
457*3ac0a46fSAndroid Build Coastguard Worker flags |= FXFONT_ITALIC;
458*3ac0a46fSAndroid Build Coastguard Worker if (FT_IS_FIXED_WIDTH(pFace))
459*3ac0a46fSAndroid Build Coastguard Worker flags |= FXFONT_FIXED_PITCH;
460*3ac0a46fSAndroid Build Coastguard Worker
461*3ac0a46fSAndroid Build Coastguard Worker TT_OS2* pOS2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(pFace, ft_sfnt_os2));
462*3ac0a46fSAndroid Build Coastguard Worker if (!pOS2)
463*3ac0a46fSAndroid Build Coastguard Worker return flags;
464*3ac0a46fSAndroid Build Coastguard Worker
465*3ac0a46fSAndroid Build Coastguard Worker if (pOS2->ulCodePageRange1 & (1 << 31))
466*3ac0a46fSAndroid Build Coastguard Worker flags |= FXFONT_SYMBOLIC;
467*3ac0a46fSAndroid Build Coastguard Worker if (pOS2->panose[0] == 2) {
468*3ac0a46fSAndroid Build Coastguard Worker uint8_t uSerif = pOS2->panose[1];
469*3ac0a46fSAndroid Build Coastguard Worker if ((uSerif > 1 && uSerif < 10) || uSerif > 13)
470*3ac0a46fSAndroid Build Coastguard Worker flags |= FXFONT_SERIF;
471*3ac0a46fSAndroid Build Coastguard Worker }
472*3ac0a46fSAndroid Build Coastguard Worker return flags;
473*3ac0a46fSAndroid Build Coastguard Worker }
474*3ac0a46fSAndroid Build Coastguard Worker
CreateFontStream(CFX_FontMapper * pFontMapper,size_t index)475*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<IFX_SeekableReadStream> CreateFontStream(CFX_FontMapper* pFontMapper,
476*3ac0a46fSAndroid Build Coastguard Worker size_t index) {
477*3ac0a46fSAndroid Build Coastguard Worker FixedUninitDataVector<uint8_t> buffer = pFontMapper->RawBytesForIndex(index);
478*3ac0a46fSAndroid Build Coastguard Worker if (buffer.empty())
479*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
480*3ac0a46fSAndroid Build Coastguard Worker
481*3ac0a46fSAndroid Build Coastguard Worker return pdfium::MakeRetain<CFX_ReadOnlyVectorStream>(std::move(buffer));
482*3ac0a46fSAndroid Build Coastguard Worker }
483*3ac0a46fSAndroid Build Coastguard Worker
CreateFontStream(const ByteString & bsFaceName)484*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<IFX_SeekableReadStream> CreateFontStream(
485*3ac0a46fSAndroid Build Coastguard Worker const ByteString& bsFaceName) {
486*3ac0a46fSAndroid Build Coastguard Worker CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
487*3ac0a46fSAndroid Build Coastguard Worker CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
488*3ac0a46fSAndroid Build Coastguard Worker pFontMapper->LoadInstalledFonts();
489*3ac0a46fSAndroid Build Coastguard Worker
490*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
491*3ac0a46fSAndroid Build Coastguard Worker if (pFontMapper->GetFaceName(i) == bsFaceName)
492*3ac0a46fSAndroid Build Coastguard Worker return CreateFontStream(pFontMapper, i);
493*3ac0a46fSAndroid Build Coastguard Worker }
494*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
495*3ac0a46fSAndroid Build Coastguard Worker }
496*3ac0a46fSAndroid Build Coastguard Worker
LoadFace(const RetainPtr<IFX_SeekableReadStream> & pFontStream,int32_t iFaceIndex)497*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFX_Face> LoadFace(
498*3ac0a46fSAndroid Build Coastguard Worker const RetainPtr<IFX_SeekableReadStream>& pFontStream,
499*3ac0a46fSAndroid Build Coastguard Worker int32_t iFaceIndex) {
500*3ac0a46fSAndroid Build Coastguard Worker if (!pFontStream)
501*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
502*3ac0a46fSAndroid Build Coastguard Worker
503*3ac0a46fSAndroid Build Coastguard Worker CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
504*3ac0a46fSAndroid Build Coastguard Worker FXFT_LibraryRec* library = pFontMgr->GetFTLibrary();
505*3ac0a46fSAndroid Build Coastguard Worker if (!library)
506*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
507*3ac0a46fSAndroid Build Coastguard Worker
508*3ac0a46fSAndroid Build Coastguard Worker // TODO(palmer): This memory will be freed with |ft_free| (which is |free|).
509*3ac0a46fSAndroid Build Coastguard Worker // Ultimately, we want to change this to:
510*3ac0a46fSAndroid Build Coastguard Worker // FXFT_Stream ftStream = FX_Alloc(FXFT_StreamRec, 1);
511*3ac0a46fSAndroid Build Coastguard Worker // https://bugs.chromium.org/p/pdfium/issues/detail?id=690
512*3ac0a46fSAndroid Build Coastguard Worker FXFT_StreamRec* ftStream =
513*3ac0a46fSAndroid Build Coastguard Worker static_cast<FXFT_StreamRec*>(ft_scalloc(sizeof(FXFT_StreamRec), 1));
514*3ac0a46fSAndroid Build Coastguard Worker memset(ftStream, 0, sizeof(FXFT_StreamRec));
515*3ac0a46fSAndroid Build Coastguard Worker ftStream->base = nullptr;
516*3ac0a46fSAndroid Build Coastguard Worker ftStream->descriptor.pointer = static_cast<void*>(pFontStream.Get());
517*3ac0a46fSAndroid Build Coastguard Worker ftStream->pos = 0;
518*3ac0a46fSAndroid Build Coastguard Worker ftStream->size = static_cast<unsigned long>(pFontStream->GetSize());
519*3ac0a46fSAndroid Build Coastguard Worker ftStream->read = ftStreamRead;
520*3ac0a46fSAndroid Build Coastguard Worker ftStream->close = ftStreamClose;
521*3ac0a46fSAndroid Build Coastguard Worker
522*3ac0a46fSAndroid Build Coastguard Worker FT_Open_Args ftArgs;
523*3ac0a46fSAndroid Build Coastguard Worker memset(&ftArgs, 0, sizeof(FT_Open_Args));
524*3ac0a46fSAndroid Build Coastguard Worker ftArgs.flags |= FT_OPEN_STREAM;
525*3ac0a46fSAndroid Build Coastguard Worker ftArgs.stream = ftStream;
526*3ac0a46fSAndroid Build Coastguard Worker
527*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFX_Face> pFace = CFX_Face::Open(library, &ftArgs, iFaceIndex);
528*3ac0a46fSAndroid Build Coastguard Worker if (!pFace) {
529*3ac0a46fSAndroid Build Coastguard Worker ft_sfree(ftStream);
530*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
531*3ac0a46fSAndroid Build Coastguard Worker }
532*3ac0a46fSAndroid Build Coastguard Worker FT_Set_Pixel_Sizes(pFace->GetRec(), 0, 64);
533*3ac0a46fSAndroid Build Coastguard Worker return pFace;
534*3ac0a46fSAndroid Build Coastguard Worker }
535*3ac0a46fSAndroid Build Coastguard Worker
VerifyUnicodeForFontDescriptor(CFGAS_FontDescriptor * pDesc,wchar_t wcUnicode)536*3ac0a46fSAndroid Build Coastguard Worker bool VerifyUnicodeForFontDescriptor(CFGAS_FontDescriptor* pDesc,
537*3ac0a46fSAndroid Build Coastguard Worker wchar_t wcUnicode) {
538*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<IFX_SeekableReadStream> pFileRead =
539*3ac0a46fSAndroid Build Coastguard Worker CreateFontStream(pDesc->m_wsFaceName.ToUTF8());
540*3ac0a46fSAndroid Build Coastguard Worker if (!pFileRead)
541*3ac0a46fSAndroid Build Coastguard Worker return false;
542*3ac0a46fSAndroid Build Coastguard Worker
543*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFX_Face> pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex);
544*3ac0a46fSAndroid Build Coastguard Worker if (!pFace)
545*3ac0a46fSAndroid Build Coastguard Worker return false;
546*3ac0a46fSAndroid Build Coastguard Worker
547*3ac0a46fSAndroid Build Coastguard Worker FT_Error retCharmap =
548*3ac0a46fSAndroid Build Coastguard Worker FXFT_Select_Charmap(pFace->GetRec(), FT_ENCODING_UNICODE);
549*3ac0a46fSAndroid Build Coastguard Worker FT_Error retIndex = FT_Get_Char_Index(pFace->GetRec(), wcUnicode);
550*3ac0a46fSAndroid Build Coastguard Worker
551*3ac0a46fSAndroid Build Coastguard Worker if (FXFT_Get_Face_External_Stream(pFace->GetRec()))
552*3ac0a46fSAndroid Build Coastguard Worker FXFT_Clear_Face_External_Stream(pFace->GetRec());
553*3ac0a46fSAndroid Build Coastguard Worker
554*3ac0a46fSAndroid Build Coastguard Worker return !retCharmap && retIndex;
555*3ac0a46fSAndroid Build Coastguard Worker }
556*3ac0a46fSAndroid Build Coastguard Worker
IsPartName(const WideString & name1,const WideString & name2)557*3ac0a46fSAndroid Build Coastguard Worker bool IsPartName(const WideString& name1, const WideString& name2) {
558*3ac0a46fSAndroid Build Coastguard Worker return name1.Contains(name2.AsStringView());
559*3ac0a46fSAndroid Build Coastguard Worker }
560*3ac0a46fSAndroid Build Coastguard Worker
CalcPenalty(CFGAS_FontDescriptor * pInstalled,FX_CodePage wCodePage,uint32_t dwFontStyles,const WideString & FontName,wchar_t wcUnicode)561*3ac0a46fSAndroid Build Coastguard Worker int32_t CalcPenalty(CFGAS_FontDescriptor* pInstalled,
562*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage wCodePage,
563*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles,
564*3ac0a46fSAndroid Build Coastguard Worker const WideString& FontName,
565*3ac0a46fSAndroid Build Coastguard Worker wchar_t wcUnicode) {
566*3ac0a46fSAndroid Build Coastguard Worker int32_t nPenalty = 30000;
567*3ac0a46fSAndroid Build Coastguard Worker if (FontName.GetLength() != 0) {
568*3ac0a46fSAndroid Build Coastguard Worker if (FontName != pInstalled->m_wsFaceName) {
569*3ac0a46fSAndroid Build Coastguard Worker size_t i;
570*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < pInstalled->m_wsFamilyNames.size(); ++i) {
571*3ac0a46fSAndroid Build Coastguard Worker if (pInstalled->m_wsFamilyNames[i] == FontName)
572*3ac0a46fSAndroid Build Coastguard Worker break;
573*3ac0a46fSAndroid Build Coastguard Worker }
574*3ac0a46fSAndroid Build Coastguard Worker if (i == pInstalled->m_wsFamilyNames.size())
575*3ac0a46fSAndroid Build Coastguard Worker nPenalty += 0xFFFF;
576*3ac0a46fSAndroid Build Coastguard Worker else
577*3ac0a46fSAndroid Build Coastguard Worker nPenalty -= 28000;
578*3ac0a46fSAndroid Build Coastguard Worker } else {
579*3ac0a46fSAndroid Build Coastguard Worker nPenalty -= 30000;
580*3ac0a46fSAndroid Build Coastguard Worker }
581*3ac0a46fSAndroid Build Coastguard Worker if (nPenalty == 30000 && !IsPartName(pInstalled->m_wsFaceName, FontName)) {
582*3ac0a46fSAndroid Build Coastguard Worker size_t i;
583*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < pInstalled->m_wsFamilyNames.size(); i++) {
584*3ac0a46fSAndroid Build Coastguard Worker if (IsPartName(pInstalled->m_wsFamilyNames[i], FontName))
585*3ac0a46fSAndroid Build Coastguard Worker break;
586*3ac0a46fSAndroid Build Coastguard Worker }
587*3ac0a46fSAndroid Build Coastguard Worker if (i == pInstalled->m_wsFamilyNames.size())
588*3ac0a46fSAndroid Build Coastguard Worker nPenalty += 0xFFFF;
589*3ac0a46fSAndroid Build Coastguard Worker else
590*3ac0a46fSAndroid Build Coastguard Worker nPenalty -= 26000;
591*3ac0a46fSAndroid Build Coastguard Worker } else {
592*3ac0a46fSAndroid Build Coastguard Worker nPenalty -= 27000;
593*3ac0a46fSAndroid Build Coastguard Worker }
594*3ac0a46fSAndroid Build Coastguard Worker }
595*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwStyleMask = pInstalled->m_dwFontStyles ^ dwFontStyles;
596*3ac0a46fSAndroid Build Coastguard Worker if (FontStyleIsForceBold(dwStyleMask))
597*3ac0a46fSAndroid Build Coastguard Worker nPenalty += 4500;
598*3ac0a46fSAndroid Build Coastguard Worker if (FontStyleIsFixedPitch(dwStyleMask))
599*3ac0a46fSAndroid Build Coastguard Worker nPenalty += 10000;
600*3ac0a46fSAndroid Build Coastguard Worker if (FontStyleIsItalic(dwStyleMask))
601*3ac0a46fSAndroid Build Coastguard Worker nPenalty += 10000;
602*3ac0a46fSAndroid Build Coastguard Worker if (FontStyleIsSerif(dwStyleMask))
603*3ac0a46fSAndroid Build Coastguard Worker nPenalty += 500;
604*3ac0a46fSAndroid Build Coastguard Worker if (FontStyleIsSymbolic(dwStyleMask))
605*3ac0a46fSAndroid Build Coastguard Worker nPenalty += 0xFFFF;
606*3ac0a46fSAndroid Build Coastguard Worker if (nPenalty >= 0xFFFF)
607*3ac0a46fSAndroid Build Coastguard Worker return 0xFFFF;
608*3ac0a46fSAndroid Build Coastguard Worker
609*3ac0a46fSAndroid Build Coastguard Worker uint16_t wBit =
610*3ac0a46fSAndroid Build Coastguard Worker (wCodePage == FX_CodePage::kDefANSI || wCodePage == FX_CodePage::kFailure)
611*3ac0a46fSAndroid Build Coastguard Worker ? static_cast<uint16_t>(-1)
612*3ac0a46fSAndroid Build Coastguard Worker : FX_GetCodePageBit(wCodePage);
613*3ac0a46fSAndroid Build Coastguard Worker if (wBit != static_cast<uint16_t>(-1)) {
614*3ac0a46fSAndroid Build Coastguard Worker DCHECK(wBit < 64);
615*3ac0a46fSAndroid Build Coastguard Worker if ((pInstalled->m_dwCsb[wBit / 32] & (1 << (wBit % 32))) == 0)
616*3ac0a46fSAndroid Build Coastguard Worker nPenalty += 0xFFFF;
617*3ac0a46fSAndroid Build Coastguard Worker else
618*3ac0a46fSAndroid Build Coastguard Worker nPenalty -= 60000;
619*3ac0a46fSAndroid Build Coastguard Worker }
620*3ac0a46fSAndroid Build Coastguard Worker wBit = (wcUnicode == 0 || wcUnicode == 0xFFFE) ? FGAS_FONTUSB::kNoBitField
621*3ac0a46fSAndroid Build Coastguard Worker : FX_GetUnicodeBit(wcUnicode);
622*3ac0a46fSAndroid Build Coastguard Worker if (wBit != FGAS_FONTUSB::kNoBitField) {
623*3ac0a46fSAndroid Build Coastguard Worker DCHECK(wBit < 128);
624*3ac0a46fSAndroid Build Coastguard Worker if ((pInstalled->m_dwUsb[wBit / 32] & (1 << (wBit % 32))) == 0)
625*3ac0a46fSAndroid Build Coastguard Worker nPenalty += 0xFFFF;
626*3ac0a46fSAndroid Build Coastguard Worker else
627*3ac0a46fSAndroid Build Coastguard Worker nPenalty -= 60000;
628*3ac0a46fSAndroid Build Coastguard Worker }
629*3ac0a46fSAndroid Build Coastguard Worker return nPenalty;
630*3ac0a46fSAndroid Build Coastguard Worker }
631*3ac0a46fSAndroid Build Coastguard Worker
632*3ac0a46fSAndroid Build Coastguard Worker } // namespace
633*3ac0a46fSAndroid Build Coastguard Worker
634*3ac0a46fSAndroid Build Coastguard Worker CFGAS_FontDescriptor::CFGAS_FontDescriptor() = default;
635*3ac0a46fSAndroid Build Coastguard Worker
636*3ac0a46fSAndroid Build Coastguard Worker CFGAS_FontDescriptor::~CFGAS_FontDescriptor() = default;
637*3ac0a46fSAndroid Build Coastguard Worker
638*3ac0a46fSAndroid Build Coastguard Worker CFGAS_FontMgr::CFGAS_FontMgr() = default;
639*3ac0a46fSAndroid Build Coastguard Worker
640*3ac0a46fSAndroid Build Coastguard Worker CFGAS_FontMgr::~CFGAS_FontMgr() = default;
641*3ac0a46fSAndroid Build Coastguard Worker
EnumFontsFromFontMapper()642*3ac0a46fSAndroid Build Coastguard Worker bool CFGAS_FontMgr::EnumFontsFromFontMapper() {
643*3ac0a46fSAndroid Build Coastguard Worker CFX_FontMapper* pFontMapper =
644*3ac0a46fSAndroid Build Coastguard Worker CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper();
645*3ac0a46fSAndroid Build Coastguard Worker pFontMapper->LoadInstalledFonts();
646*3ac0a46fSAndroid Build Coastguard Worker
647*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
648*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<IFX_SeekableReadStream> pFontStream =
649*3ac0a46fSAndroid Build Coastguard Worker CreateFontStream(pFontMapper, i);
650*3ac0a46fSAndroid Build Coastguard Worker if (!pFontStream)
651*3ac0a46fSAndroid Build Coastguard Worker continue;
652*3ac0a46fSAndroid Build Coastguard Worker
653*3ac0a46fSAndroid Build Coastguard Worker WideString wsFaceName =
654*3ac0a46fSAndroid Build Coastguard Worker WideString::FromDefANSI(pFontMapper->GetFaceName(i).AsStringView());
655*3ac0a46fSAndroid Build Coastguard Worker RegisterFaces(pFontStream, wsFaceName);
656*3ac0a46fSAndroid Build Coastguard Worker }
657*3ac0a46fSAndroid Build Coastguard Worker
658*3ac0a46fSAndroid Build Coastguard Worker return !m_InstalledFonts.empty();
659*3ac0a46fSAndroid Build Coastguard Worker }
660*3ac0a46fSAndroid Build Coastguard Worker
EnumFonts()661*3ac0a46fSAndroid Build Coastguard Worker bool CFGAS_FontMgr::EnumFonts() {
662*3ac0a46fSAndroid Build Coastguard Worker return EnumFontsFromFontMapper();
663*3ac0a46fSAndroid Build Coastguard Worker }
664*3ac0a46fSAndroid Build Coastguard Worker
GetFontByUnicodeImpl(wchar_t wUnicode,uint32_t dwFontStyles,const wchar_t * pszFontFamily,uint32_t dwHash,FX_CodePage wCodePage,uint16_t)665*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicodeImpl(
666*3ac0a46fSAndroid Build Coastguard Worker wchar_t wUnicode,
667*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles,
668*3ac0a46fSAndroid Build Coastguard Worker const wchar_t* pszFontFamily,
669*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwHash,
670*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage wCodePage,
671*3ac0a46fSAndroid Build Coastguard Worker uint16_t /* wBitField*/) {
672*3ac0a46fSAndroid Build Coastguard Worker if (!pdfium::Contains(m_Hash2CandidateList, dwHash)) {
673*3ac0a46fSAndroid Build Coastguard Worker m_Hash2CandidateList[dwHash] =
674*3ac0a46fSAndroid Build Coastguard Worker MatchFonts(wCodePage, dwFontStyles, pszFontFamily, wUnicode);
675*3ac0a46fSAndroid Build Coastguard Worker }
676*3ac0a46fSAndroid Build Coastguard Worker for (const auto& info : m_Hash2CandidateList[dwHash]) {
677*3ac0a46fSAndroid Build Coastguard Worker CFGAS_FontDescriptor* pDesc = info.pFont;
678*3ac0a46fSAndroid Build Coastguard Worker if (!VerifyUnicodeForFontDescriptor(pDesc, wUnicode))
679*3ac0a46fSAndroid Build Coastguard Worker continue;
680*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFGAS_GEFont> pFont =
681*3ac0a46fSAndroid Build Coastguard Worker LoadFontInternal(pDesc->m_wsFaceName, pDesc->m_nFaceIndex);
682*3ac0a46fSAndroid Build Coastguard Worker if (!pFont)
683*3ac0a46fSAndroid Build Coastguard Worker continue;
684*3ac0a46fSAndroid Build Coastguard Worker pFont->SetLogicalFontStyle(dwFontStyles);
685*3ac0a46fSAndroid Build Coastguard Worker m_Hash2Fonts[dwHash].push_back(pFont);
686*3ac0a46fSAndroid Build Coastguard Worker return pFont;
687*3ac0a46fSAndroid Build Coastguard Worker }
688*3ac0a46fSAndroid Build Coastguard Worker if (!pszFontFamily)
689*3ac0a46fSAndroid Build Coastguard Worker m_FailedUnicodesSet.insert(wUnicode);
690*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
691*3ac0a46fSAndroid Build Coastguard Worker }
692*3ac0a46fSAndroid Build Coastguard Worker
LoadFontInternal(const WideString & wsFaceName,int32_t iFaceIndex)693*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFontInternal(
694*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsFaceName,
695*3ac0a46fSAndroid Build Coastguard Worker int32_t iFaceIndex) {
696*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<IFX_SeekableReadStream> pFontStream =
697*3ac0a46fSAndroid Build Coastguard Worker CreateFontStream(wsFaceName.ToUTF8());
698*3ac0a46fSAndroid Build Coastguard Worker if (!pFontStream)
699*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
700*3ac0a46fSAndroid Build Coastguard Worker
701*3ac0a46fSAndroid Build Coastguard Worker auto pInternalFont = std::make_unique<CFX_Font>();
702*3ac0a46fSAndroid Build Coastguard Worker if (!pInternalFont->LoadFile(std::move(pFontStream), iFaceIndex))
703*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
704*3ac0a46fSAndroid Build Coastguard Worker
705*3ac0a46fSAndroid Build Coastguard Worker return CFGAS_GEFont::LoadFont(std::move(pInternalFont));
706*3ac0a46fSAndroid Build Coastguard Worker }
707*3ac0a46fSAndroid Build Coastguard Worker
MatchFonts(FX_CodePage wCodePage,uint32_t dwFontStyles,const WideString & FontName,wchar_t wcUnicode)708*3ac0a46fSAndroid Build Coastguard Worker std::vector<CFGAS_FontDescriptorInfo> CFGAS_FontMgr::MatchFonts(
709*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage wCodePage,
710*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles,
711*3ac0a46fSAndroid Build Coastguard Worker const WideString& FontName,
712*3ac0a46fSAndroid Build Coastguard Worker wchar_t wcUnicode) {
713*3ac0a46fSAndroid Build Coastguard Worker std::vector<CFGAS_FontDescriptorInfo> matched_fonts;
714*3ac0a46fSAndroid Build Coastguard Worker for (const auto& pFont : m_InstalledFonts) {
715*3ac0a46fSAndroid Build Coastguard Worker int32_t nPenalty =
716*3ac0a46fSAndroid Build Coastguard Worker CalcPenalty(pFont.get(), wCodePage, dwFontStyles, FontName, wcUnicode);
717*3ac0a46fSAndroid Build Coastguard Worker if (nPenalty >= 0xffff)
718*3ac0a46fSAndroid Build Coastguard Worker continue;
719*3ac0a46fSAndroid Build Coastguard Worker matched_fonts.push_back({pFont.get(), nPenalty});
720*3ac0a46fSAndroid Build Coastguard Worker if (matched_fonts.size() == 0xffff)
721*3ac0a46fSAndroid Build Coastguard Worker break;
722*3ac0a46fSAndroid Build Coastguard Worker }
723*3ac0a46fSAndroid Build Coastguard Worker std::stable_sort(matched_fonts.begin(), matched_fonts.end());
724*3ac0a46fSAndroid Build Coastguard Worker return matched_fonts;
725*3ac0a46fSAndroid Build Coastguard Worker }
726*3ac0a46fSAndroid Build Coastguard Worker
RegisterFace(RetainPtr<CFX_Face> pFace,const WideString & wsFaceName)727*3ac0a46fSAndroid Build Coastguard Worker void CFGAS_FontMgr::RegisterFace(RetainPtr<CFX_Face> pFace,
728*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsFaceName) {
729*3ac0a46fSAndroid Build Coastguard Worker if ((pFace->GetRec()->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
730*3ac0a46fSAndroid Build Coastguard Worker return;
731*3ac0a46fSAndroid Build Coastguard Worker
732*3ac0a46fSAndroid Build Coastguard Worker auto pFont = std::make_unique<CFGAS_FontDescriptor>();
733*3ac0a46fSAndroid Build Coastguard Worker pFont->m_dwFontStyles |= GetFlags(pFace->GetRec());
734*3ac0a46fSAndroid Build Coastguard Worker
735*3ac0a46fSAndroid Build Coastguard Worker GetUSBCSB(pFace->GetRec(), pFont->m_dwUsb, pFont->m_dwCsb);
736*3ac0a46fSAndroid Build Coastguard Worker
737*3ac0a46fSAndroid Build Coastguard Worker FT_ULong dwTag;
738*3ac0a46fSAndroid Build Coastguard Worker FT_ENC_TAG(dwTag, 'n', 'a', 'm', 'e');
739*3ac0a46fSAndroid Build Coastguard Worker
740*3ac0a46fSAndroid Build Coastguard Worker DataVector<uint8_t> table;
741*3ac0a46fSAndroid Build Coastguard Worker unsigned long nLength = 0;
742*3ac0a46fSAndroid Build Coastguard Worker unsigned int error =
743*3ac0a46fSAndroid Build Coastguard Worker FT_Load_Sfnt_Table(pFace->GetRec(), dwTag, 0, nullptr, &nLength);
744*3ac0a46fSAndroid Build Coastguard Worker if (error == 0 && nLength != 0) {
745*3ac0a46fSAndroid Build Coastguard Worker table.resize(nLength);
746*3ac0a46fSAndroid Build Coastguard Worker if (FT_Load_Sfnt_Table(pFace->GetRec(), dwTag, 0, table.data(), nullptr))
747*3ac0a46fSAndroid Build Coastguard Worker table.clear();
748*3ac0a46fSAndroid Build Coastguard Worker }
749*3ac0a46fSAndroid Build Coastguard Worker pFont->m_wsFamilyNames = GetNames(table);
750*3ac0a46fSAndroid Build Coastguard Worker pFont->m_wsFamilyNames.push_back(
751*3ac0a46fSAndroid Build Coastguard Worker WideString::FromUTF8(pFace->GetRec()->family_name));
752*3ac0a46fSAndroid Build Coastguard Worker pFont->m_wsFaceName = wsFaceName;
753*3ac0a46fSAndroid Build Coastguard Worker pFont->m_nFaceIndex =
754*3ac0a46fSAndroid Build Coastguard Worker pdfium::base::checked_cast<int32_t>(pFace->GetRec()->face_index);
755*3ac0a46fSAndroid Build Coastguard Worker m_InstalledFonts.push_back(std::move(pFont));
756*3ac0a46fSAndroid Build Coastguard Worker }
757*3ac0a46fSAndroid Build Coastguard Worker
RegisterFaces(const RetainPtr<IFX_SeekableReadStream> & pFontStream,const WideString & wsFaceName)758*3ac0a46fSAndroid Build Coastguard Worker void CFGAS_FontMgr::RegisterFaces(
759*3ac0a46fSAndroid Build Coastguard Worker const RetainPtr<IFX_SeekableReadStream>& pFontStream,
760*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsFaceName) {
761*3ac0a46fSAndroid Build Coastguard Worker int32_t index = 0;
762*3ac0a46fSAndroid Build Coastguard Worker int32_t num_faces = 0;
763*3ac0a46fSAndroid Build Coastguard Worker do {
764*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFX_Face> pFace = LoadFace(pFontStream, index++);
765*3ac0a46fSAndroid Build Coastguard Worker if (!pFace)
766*3ac0a46fSAndroid Build Coastguard Worker continue;
767*3ac0a46fSAndroid Build Coastguard Worker // All faces keep number of faces. It can be retrieved from any one face.
768*3ac0a46fSAndroid Build Coastguard Worker if (num_faces == 0) {
769*3ac0a46fSAndroid Build Coastguard Worker num_faces =
770*3ac0a46fSAndroid Build Coastguard Worker pdfium::base::checked_cast<int32_t>(pFace->GetRec()->num_faces);
771*3ac0a46fSAndroid Build Coastguard Worker }
772*3ac0a46fSAndroid Build Coastguard Worker RegisterFace(pFace, wsFaceName);
773*3ac0a46fSAndroid Build Coastguard Worker if (FXFT_Get_Face_External_Stream(pFace->GetRec()))
774*3ac0a46fSAndroid Build Coastguard Worker FXFT_Clear_Face_External_Stream(pFace->GetRec());
775*3ac0a46fSAndroid Build Coastguard Worker } while (index < num_faces);
776*3ac0a46fSAndroid Build Coastguard Worker }
777*3ac0a46fSAndroid Build Coastguard Worker
778*3ac0a46fSAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
779*3ac0a46fSAndroid Build Coastguard Worker
GetFontByCodePage(FX_CodePage wCodePage,uint32_t dwFontStyles,const wchar_t * pszFontFamily)780*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage(
781*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage wCodePage,
782*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles,
783*3ac0a46fSAndroid Build Coastguard Worker const wchar_t* pszFontFamily) {
784*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwHash = ShortFormHash(wCodePage, dwFontStyles, pszFontFamily);
785*3ac0a46fSAndroid Build Coastguard Worker auto* pFontVector = &m_Hash2Fonts[dwHash];
786*3ac0a46fSAndroid Build Coastguard Worker if (!pFontVector->empty()) {
787*3ac0a46fSAndroid Build Coastguard Worker for (auto iter = pFontVector->begin(); iter != pFontVector->end(); ++iter) {
788*3ac0a46fSAndroid Build Coastguard Worker if (*iter != nullptr)
789*3ac0a46fSAndroid Build Coastguard Worker return *iter;
790*3ac0a46fSAndroid Build Coastguard Worker }
791*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
792*3ac0a46fSAndroid Build Coastguard Worker }
793*3ac0a46fSAndroid Build Coastguard Worker
794*3ac0a46fSAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
795*3ac0a46fSAndroid Build Coastguard Worker const FX_FONTDESCRIPTOR* pFD =
796*3ac0a46fSAndroid Build Coastguard Worker FindFont(pszFontFamily, dwFontStyles, true, wCodePage,
797*3ac0a46fSAndroid Build Coastguard Worker FGAS_FONTUSB::kNoBitField, 0);
798*3ac0a46fSAndroid Build Coastguard Worker if (!pFD) {
799*3ac0a46fSAndroid Build Coastguard Worker pFD = FindFont(nullptr, dwFontStyles, true, wCodePage,
800*3ac0a46fSAndroid Build Coastguard Worker FGAS_FONTUSB::kNoBitField, 0);
801*3ac0a46fSAndroid Build Coastguard Worker }
802*3ac0a46fSAndroid Build Coastguard Worker if (!pFD) {
803*3ac0a46fSAndroid Build Coastguard Worker pFD = FindFont(nullptr, dwFontStyles, false, wCodePage,
804*3ac0a46fSAndroid Build Coastguard Worker FGAS_FONTUSB::kNoBitField, 0);
805*3ac0a46fSAndroid Build Coastguard Worker }
806*3ac0a46fSAndroid Build Coastguard Worker if (!pFD)
807*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
808*3ac0a46fSAndroid Build Coastguard Worker
809*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFGAS_GEFont> pFont =
810*3ac0a46fSAndroid Build Coastguard Worker CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage);
811*3ac0a46fSAndroid Build Coastguard Worker #else // BUILDFLAG(IS_WIN)
812*3ac0a46fSAndroid Build Coastguard Worker if (!pdfium::Contains(m_Hash2CandidateList, dwHash)) {
813*3ac0a46fSAndroid Build Coastguard Worker m_Hash2CandidateList[dwHash] =
814*3ac0a46fSAndroid Build Coastguard Worker MatchFonts(wCodePage, dwFontStyles, WideString(pszFontFamily), 0);
815*3ac0a46fSAndroid Build Coastguard Worker }
816*3ac0a46fSAndroid Build Coastguard Worker if (m_Hash2CandidateList[dwHash].empty())
817*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
818*3ac0a46fSAndroid Build Coastguard Worker
819*3ac0a46fSAndroid Build Coastguard Worker CFGAS_FontDescriptor* pDesc = m_Hash2CandidateList[dwHash].front().pFont;
820*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFGAS_GEFont> pFont =
821*3ac0a46fSAndroid Build Coastguard Worker LoadFontInternal(pDesc->m_wsFaceName, pDesc->m_nFaceIndex);
822*3ac0a46fSAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
823*3ac0a46fSAndroid Build Coastguard Worker
824*3ac0a46fSAndroid Build Coastguard Worker if (!pFont)
825*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
826*3ac0a46fSAndroid Build Coastguard Worker
827*3ac0a46fSAndroid Build Coastguard Worker pFont->SetLogicalFontStyle(dwFontStyles);
828*3ac0a46fSAndroid Build Coastguard Worker pFontVector->push_back(pFont);
829*3ac0a46fSAndroid Build Coastguard Worker return pFont;
830*3ac0a46fSAndroid Build Coastguard Worker }
831*3ac0a46fSAndroid Build Coastguard Worker
GetFontByUnicode(wchar_t wUnicode,uint32_t dwFontStyles,const wchar_t * pszFontFamily)832*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicode(
833*3ac0a46fSAndroid Build Coastguard Worker wchar_t wUnicode,
834*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles,
835*3ac0a46fSAndroid Build Coastguard Worker const wchar_t* pszFontFamily) {
836*3ac0a46fSAndroid Build Coastguard Worker if (pdfium::Contains(m_FailedUnicodesSet, wUnicode))
837*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
838*3ac0a46fSAndroid Build Coastguard Worker
839*3ac0a46fSAndroid Build Coastguard Worker const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wUnicode);
840*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage wCodePage = x ? x->wCodePage : FX_CodePage::kFailure;
841*3ac0a46fSAndroid Build Coastguard Worker uint16_t wBitField = x ? x->wBitField : FGAS_FONTUSB::kNoBitField;
842*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwHash =
843*3ac0a46fSAndroid Build Coastguard Worker wCodePage == FX_CodePage::kFailure
844*3ac0a46fSAndroid Build Coastguard Worker ? LongFormHash(wCodePage, wBitField, dwFontStyles, pszFontFamily)
845*3ac0a46fSAndroid Build Coastguard Worker : ShortFormHash(wCodePage, dwFontStyles, pszFontFamily);
846*3ac0a46fSAndroid Build Coastguard Worker for (auto& pFont : m_Hash2Fonts[dwHash]) {
847*3ac0a46fSAndroid Build Coastguard Worker if (VerifyUnicode(pFont, wUnicode))
848*3ac0a46fSAndroid Build Coastguard Worker return pFont;
849*3ac0a46fSAndroid Build Coastguard Worker }
850*3ac0a46fSAndroid Build Coastguard Worker return GetFontByUnicodeImpl(wUnicode, dwFontStyles, pszFontFamily, dwHash,
851*3ac0a46fSAndroid Build Coastguard Worker wCodePage, wBitField);
852*3ac0a46fSAndroid Build Coastguard Worker }
853*3ac0a46fSAndroid Build Coastguard Worker
LoadFont(const wchar_t * pszFontFamily,uint32_t dwFontStyles,FX_CodePage wCodePage)854*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(const wchar_t* pszFontFamily,
855*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFontStyles,
856*3ac0a46fSAndroid Build Coastguard Worker FX_CodePage wCodePage) {
857*3ac0a46fSAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
858*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwHash = ShortFormHash(wCodePage, dwFontStyles, pszFontFamily);
859*3ac0a46fSAndroid Build Coastguard Worker std::vector<RetainPtr<CFGAS_GEFont>>* pFontArray = &m_Hash2Fonts[dwHash];
860*3ac0a46fSAndroid Build Coastguard Worker if (!pFontArray->empty())
861*3ac0a46fSAndroid Build Coastguard Worker return pFontArray->front();
862*3ac0a46fSAndroid Build Coastguard Worker
863*3ac0a46fSAndroid Build Coastguard Worker const FX_FONTDESCRIPTOR* pFD =
864*3ac0a46fSAndroid Build Coastguard Worker FindFont(pszFontFamily, dwFontStyles, true, wCodePage,
865*3ac0a46fSAndroid Build Coastguard Worker FGAS_FONTUSB::kNoBitField, 0);
866*3ac0a46fSAndroid Build Coastguard Worker if (!pFD) {
867*3ac0a46fSAndroid Build Coastguard Worker pFD = FindFont(pszFontFamily, dwFontStyles, false, wCodePage,
868*3ac0a46fSAndroid Build Coastguard Worker FGAS_FONTUSB::kNoBitField, 0);
869*3ac0a46fSAndroid Build Coastguard Worker }
870*3ac0a46fSAndroid Build Coastguard Worker if (!pFD)
871*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
872*3ac0a46fSAndroid Build Coastguard Worker
873*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CFGAS_GEFont> pFont =
874*3ac0a46fSAndroid Build Coastguard Worker CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage);
875*3ac0a46fSAndroid Build Coastguard Worker if (!pFont)
876*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
877*3ac0a46fSAndroid Build Coastguard Worker
878*3ac0a46fSAndroid Build Coastguard Worker pFont->SetLogicalFontStyle(dwFontStyles);
879*3ac0a46fSAndroid Build Coastguard Worker pFontArray->push_back(pFont);
880*3ac0a46fSAndroid Build Coastguard Worker return pFont;
881*3ac0a46fSAndroid Build Coastguard Worker #else // BUILDFLAG(IS_WIN)
882*3ac0a46fSAndroid Build Coastguard Worker return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
883*3ac0a46fSAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
884*3ac0a46fSAndroid Build Coastguard Worker }
885