xref: /aosp_15_r20/external/pdfium/xfa/fgas/font/cfgas_fontmgr.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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(&params, 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(&params, 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(&params, 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