Home | History | Annotate | Download | only in font
      1 // Copyright 2015 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "xfa/fgas/font/cfgas_fontmgr.h"
      8 
      9 #include <algorithm>
     10 #include <memory>
     11 #include <utility>
     12 
     13 #include "core/fxcrt/fx_stream.h"
     14 #include "core/fxge/cfx_fontmapper.h"
     15 #include "core/fxge/cfx_fontmgr.h"
     16 #include "core/fxge/cfx_gemodule.h"
     17 #include "core/fxge/ifx_systemfontinfo.h"
     18 #include "third_party/base/ptr_util.h"
     19 #include "third_party/base/stl_util.h"
     20 #include "xfa/fgas/crt/fgas_codepage.h"
     21 #include "xfa/fgas/font/cfgas_gefont.h"
     22 #include "xfa/fgas/font/fgas_fontutils.h"
     23 
     24 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
     25 
     26 namespace {
     27 
     28 int32_t GetSimilarityScore(FX_FONTDESCRIPTOR const* pFont,
     29                            uint32_t dwFontStyles) {
     30   int32_t iValue = 0;
     31   if ((dwFontStyles & FX_FONTSTYLE_Symbolic) ==
     32       (pFont->dwFontStyles & FX_FONTSTYLE_Symbolic)) {
     33     iValue += 64;
     34   }
     35   if ((dwFontStyles & FX_FONTSTYLE_FixedPitch) ==
     36       (pFont->dwFontStyles & FX_FONTSTYLE_FixedPitch)) {
     37     iValue += 32;
     38   }
     39   if ((dwFontStyles & FX_FONTSTYLE_Serif) ==
     40       (pFont->dwFontStyles & FX_FONTSTYLE_Serif)) {
     41     iValue += 16;
     42   }
     43   if ((dwFontStyles & FX_FONTSTYLE_Script) ==
     44       (pFont->dwFontStyles & FX_FONTSTYLE_Script)) {
     45     iValue += 8;
     46   }
     47   return iValue;
     48 }
     49 
     50 const FX_FONTDESCRIPTOR* MatchDefaultFont(
     51     FX_FONTMATCHPARAMS* pParams,
     52     const std::deque<FX_FONTDESCRIPTOR>& fonts) {
     53   const FX_FONTDESCRIPTOR* pBestFont = nullptr;
     54   int32_t iBestSimilar = 0;
     55   bool bMatchStyle = (pParams->dwMatchFlags & FX_FONTMATCHPARA_MatchStyle) > 0;
     56   for (const auto& font : fonts) {
     57     if ((font.dwFontStyles & FX_FONTSTYLE_BoldItalic) ==
     58         FX_FONTSTYLE_BoldItalic) {
     59       continue;
     60     }
     61     if (pParams->pwsFamily) {
     62       if (FXSYS_wcsicmp(pParams->pwsFamily, font.wsFontFace))
     63         continue;
     64       if (font.uCharSet == FX_CHARSET_Symbol)
     65         return &font;
     66     }
     67     if (font.uCharSet == FX_CHARSET_Symbol)
     68       continue;
     69     if (pParams->wCodePage != 0xFFFF) {
     70       if (FX_GetCodePageFromCharset(font.uCharSet) != pParams->wCodePage)
     71         continue;
     72     } else {
     73       if (pParams->dwUSB < 128) {
     74         uint32_t dwByte = pParams->dwUSB / 32;
     75         uint32_t dwUSB = 1 << (pParams->dwUSB % 32);
     76         if ((font.FontSignature.fsUsb[dwByte] & dwUSB) == 0)
     77           continue;
     78       }
     79     }
     80     if (bMatchStyle) {
     81       if ((font.dwFontStyles & 0x0F) == (pParams->dwFontStyles & 0x0F))
     82         return &font;
     83       continue;
     84     }
     85     if (pParams->pwsFamily) {
     86       if (FXSYS_wcsicmp(pParams->pwsFamily, font.wsFontFace) == 0)
     87         return &font;
     88     }
     89     int32_t iSimilarValue = GetSimilarityScore(&font, pParams->dwFontStyles);
     90     if (iBestSimilar < iSimilarValue) {
     91       iBestSimilar = iSimilarValue;
     92       pBestFont = &font;
     93     }
     94   }
     95   return iBestSimilar < 1 ? nullptr : pBestFont;
     96 }
     97 
     98 }  // namespace
     99 
    100 std::unique_ptr<CFGAS_FontMgr> CFGAS_FontMgr::Create(
    101     FX_LPEnumAllFonts pEnumerator) {
    102   return pdfium::MakeUnique<CFGAS_FontMgr>(pEnumerator);
    103 }
    104 
    105 CFGAS_FontMgr::CFGAS_FontMgr(FX_LPEnumAllFonts pEnumerator)
    106     : m_pEnumerator(pEnumerator), m_FontFaces(100) {
    107   if (m_pEnumerator)
    108     m_pEnumerator(&m_FontFaces, nullptr, 0xFEFF);
    109 }
    110 
    111 CFGAS_FontMgr::~CFGAS_FontMgr() {}
    112 
    113 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage(
    114     uint16_t wCodePage,
    115     uint32_t dwFontStyles,
    116     const FX_WCHAR* pszFontFamily) {
    117   uint32_t dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
    118   auto it = m_CPFonts.find(dwHash);
    119   if (it != m_CPFonts.end()) {
    120     return it->second ? LoadFont(it->second, dwFontStyles, wCodePage) : nullptr;
    121   }
    122   const FX_FONTDESCRIPTOR* pFD =
    123       FindFont(pszFontFamily, dwFontStyles, true, wCodePage);
    124   if (!pFD)
    125     pFD = FindFont(nullptr, dwFontStyles, true, wCodePage);
    126   if (!pFD)
    127     pFD = FindFont(nullptr, dwFontStyles, false, wCodePage);
    128   if (!pFD)
    129     return nullptr;
    130 
    131   CFX_RetainPtr<CFGAS_GEFont> pFont =
    132       CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
    133   if (!pFont)
    134     return nullptr;
    135 
    136   m_Fonts.push_back(pFont);
    137   m_CPFonts[dwHash] = pFont;
    138   dwHash = FGAS_GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage);
    139   m_FamilyFonts[dwHash] = pFont;
    140   return LoadFont(pFont, dwFontStyles, wCodePage);
    141 }
    142 
    143 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicode(
    144     FX_WCHAR wUnicode,
    145     uint32_t dwFontStyles,
    146     const FX_WCHAR* pszFontFamily) {
    147   const FGAS_FONTUSB* pRet = FGAS_GetUnicodeBitField(wUnicode);
    148   if (pRet->wBitField == 999)
    149     return nullptr;
    150 
    151   uint32_t dwHash =
    152       FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, pRet->wBitField);
    153   auto it = m_UnicodeFonts.find(dwHash);
    154   if (it != m_UnicodeFonts.end()) {
    155     return it->second ? LoadFont(it->second, dwFontStyles, pRet->wCodePage)
    156                       : nullptr;
    157   }
    158   const FX_FONTDESCRIPTOR* pFD =
    159       FindFont(pszFontFamily, dwFontStyles, false, pRet->wCodePage,
    160                pRet->wBitField, wUnicode);
    161   if (!pFD && pszFontFamily) {
    162     pFD = FindFont(nullptr, dwFontStyles, false, pRet->wCodePage,
    163                    pRet->wBitField, wUnicode);
    164   }
    165   if (!pFD)
    166     return nullptr;
    167 
    168   uint16_t wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
    169   const FX_WCHAR* pFontFace = pFD->wsFontFace;
    170   CFX_RetainPtr<CFGAS_GEFont> pFont =
    171       CFGAS_GEFont::LoadFont(pFontFace, dwFontStyles, wCodePage, this);
    172   if (!pFont)
    173     return nullptr;
    174 
    175   m_Fonts.push_back(pFont);
    176   m_UnicodeFonts[dwHash] = pFont;
    177   m_CPFonts[FGAS_GetFontHashCode(wCodePage, dwFontStyles)] = pFont;
    178   m_FamilyFonts[FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage)] =
    179       pFont;
    180   return LoadFont(pFont, dwFontStyles, wCodePage);
    181 }
    182 
    183 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(
    184     const FX_WCHAR* pszFontFamily,
    185     uint32_t dwFontStyles,
    186     uint16_t wCodePage) {
    187   CFX_RetainPtr<CFGAS_GEFont> pFont;
    188   uint32_t dwHash =
    189       FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage);
    190   auto it = m_FamilyFonts.find(dwHash);
    191   if (it != m_FamilyFonts.end())
    192     return it->second ? LoadFont(it->second, dwFontStyles, wCodePage) : nullptr;
    193 
    194   const FX_FONTDESCRIPTOR* pFD =
    195       FindFont(pszFontFamily, dwFontStyles, true, wCodePage);
    196   if (!pFD)
    197     pFD = FindFont(pszFontFamily, dwFontStyles, false, wCodePage);
    198   if (!pFD)
    199     return nullptr;
    200 
    201   if (wCodePage == 0xFFFF)
    202     wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
    203 
    204   pFont =
    205       CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
    206   if (!pFont)
    207     return nullptr;
    208 
    209   m_Fonts.push_back(pFont);
    210   m_FamilyFonts[dwHash] = pFont;
    211   dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
    212   m_CPFonts[dwHash] = pFont;
    213   return LoadFont(pFont, dwFontStyles, wCodePage);
    214 }
    215 
    216 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(
    217     const CFX_RetainPtr<CFGAS_GEFont>& pSrcFont,
    218     uint32_t dwFontStyles,
    219     uint16_t wCodePage) {
    220   if (pSrcFont->GetFontStyles() == dwFontStyles)
    221     return pSrcFont;
    222 
    223   void* buffer[3] = {pSrcFont.Get(), (void*)(uintptr_t)dwFontStyles,
    224                      (void*)(uintptr_t)wCodePage};
    225   uint32_t dwHash = FX_HashCode_GetA(
    226       CFX_ByteStringC((uint8_t*)buffer, sizeof(buffer)), false);
    227   auto it = m_DeriveFonts.find(dwHash);
    228   if (it != m_DeriveFonts.end() && it->second)
    229     return it->second;
    230 
    231   CFX_RetainPtr<CFGAS_GEFont> pFont = pSrcFont->Derive(dwFontStyles, wCodePage);
    232   if (!pFont)
    233     return nullptr;
    234 
    235   m_DeriveFonts[dwHash] = pFont;
    236   auto iter = std::find(m_Fonts.begin(), m_Fonts.end(), pFont);
    237   if (iter == m_Fonts.end())
    238     m_Fonts.push_back(pFont);
    239   return pFont;
    240 }
    241 
    242 void CFGAS_FontMgr::RemoveFont(
    243     std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>>* pFontMap,
    244     const CFX_RetainPtr<CFGAS_GEFont>& pFont) {
    245   auto iter = pFontMap->begin();
    246   while (iter != pFontMap->end()) {
    247     auto old_iter = iter++;
    248     if (old_iter->second == pFont)
    249       pFontMap->erase(old_iter);
    250   }
    251 }
    252 
    253 void CFGAS_FontMgr::RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) {
    254   RemoveFont(&m_CPFonts, pFont);
    255   RemoveFont(&m_FamilyFonts, pFont);
    256   RemoveFont(&m_UnicodeFonts, pFont);
    257   RemoveFont(&m_BufferFonts, pFont);
    258   RemoveFont(&m_StreamFonts, pFont);
    259   RemoveFont(&m_DeriveFonts, pFont);
    260   auto it = std::find(m_Fonts.begin(), m_Fonts.end(), pFont);
    261   if (it != m_Fonts.end())
    262     m_Fonts.erase(it);
    263 }
    264 
    265 const FX_FONTDESCRIPTOR* CFGAS_FontMgr::FindFont(const FX_WCHAR* pszFontFamily,
    266                                                  uint32_t dwFontStyles,
    267                                                  uint32_t dwMatchFlags,
    268                                                  uint16_t wCodePage,
    269                                                  uint32_t dwUSB,
    270                                                  FX_WCHAR wUnicode) {
    271   FX_FONTMATCHPARAMS params;
    272   FXSYS_memset(&params, 0, sizeof(params));
    273   params.dwUSB = dwUSB;
    274   params.wUnicode = wUnicode;
    275   params.wCodePage = wCodePage;
    276   params.pwsFamily = pszFontFamily;
    277   params.dwFontStyles = dwFontStyles;
    278   params.dwMatchFlags = dwMatchFlags;
    279   const FX_FONTDESCRIPTOR* pDesc = MatchDefaultFont(&params, m_FontFaces);
    280   if (pDesc)
    281     return pDesc;
    282 
    283   if (!pszFontFamily || !m_pEnumerator)
    284     return nullptr;
    285 
    286   std::deque<FX_FONTDESCRIPTOR> namedFonts;
    287   m_pEnumerator(&namedFonts, pszFontFamily, wUnicode);
    288   params.pwsFamily = nullptr;
    289   pDesc = MatchDefaultFont(&params, namedFonts);
    290   if (!pDesc)
    291     return nullptr;
    292 
    293   auto it = std::find(m_FontFaces.rbegin(), m_FontFaces.rend(), *pDesc);
    294   if (it != m_FontFaces.rend())
    295     return &*it;
    296 
    297   m_FontFaces.push_back(*pDesc);
    298   return &m_FontFaces.back();
    299 }
    300 
    301 uint32_t FX_GetGdiFontStyles(const LOGFONTW& lf) {
    302   uint32_t dwStyles = 0;
    303   if ((lf.lfPitchAndFamily & 0x03) == FIXED_PITCH)
    304     dwStyles |= FX_FONTSTYLE_FixedPitch;
    305   uint8_t nFamilies = lf.lfPitchAndFamily & 0xF0;
    306   if (nFamilies == FF_ROMAN)
    307     dwStyles |= FX_FONTSTYLE_Serif;
    308   if (nFamilies == FF_SCRIPT)
    309     dwStyles |= FX_FONTSTYLE_Script;
    310   if (lf.lfCharSet == SYMBOL_CHARSET)
    311     dwStyles |= FX_FONTSTYLE_Symbolic;
    312   return dwStyles;
    313 }
    314 
    315 static int32_t CALLBACK FX_GdiFontEnumProc(ENUMLOGFONTEX* lpelfe,
    316                                            NEWTEXTMETRICEX* lpntme,
    317                                            DWORD dwFontType,
    318                                            LPARAM lParam) {
    319   if (dwFontType != TRUETYPE_FONTTYPE)
    320     return 1;
    321   const LOGFONTW& lf = ((LPENUMLOGFONTEXW)lpelfe)->elfLogFont;
    322   if (lf.lfFaceName[0] == L'@')
    323     return 1;
    324   FX_FONTDESCRIPTOR* pFont = FX_Alloc(FX_FONTDESCRIPTOR, 1);
    325   FXSYS_memset(pFont, 0, sizeof(FX_FONTDESCRIPTOR));
    326   pFont->uCharSet = lf.lfCharSet;
    327   pFont->dwFontStyles = FX_GetGdiFontStyles(lf);
    328   FXSYS_wcsncpy(pFont->wsFontFace, (const FX_WCHAR*)lf.lfFaceName, 31);
    329   pFont->wsFontFace[31] = 0;
    330   FXSYS_memcpy(&pFont->FontSignature, &lpntme->ntmFontSig,
    331                sizeof(lpntme->ntmFontSig));
    332   reinterpret_cast<std::deque<FX_FONTDESCRIPTOR>*>(lParam)->push_back(*pFont);
    333   FX_Free(pFont);
    334   return 1;
    335 }
    336 
    337 static void FX_EnumGdiFonts(std::deque<FX_FONTDESCRIPTOR>* fonts,
    338                             const FX_WCHAR* pwsFaceName,
    339                             FX_WCHAR wUnicode) {
    340   HDC hDC = ::GetDC(nullptr);
    341   LOGFONTW lfFind;
    342   FXSYS_memset(&lfFind, 0, sizeof(lfFind));
    343   lfFind.lfCharSet = DEFAULT_CHARSET;
    344   if (pwsFaceName) {
    345     FXSYS_wcsncpy(lfFind.lfFaceName, pwsFaceName, 31);
    346     lfFind.lfFaceName[31] = 0;
    347   }
    348   EnumFontFamiliesExW(hDC, (LPLOGFONTW)&lfFind,
    349                       (FONTENUMPROCW)FX_GdiFontEnumProc, (LPARAM)fonts, 0);
    350   ::ReleaseDC(nullptr, hDC);
    351 }
    352 
    353 FX_LPEnumAllFonts FX_GetDefFontEnumerator() {
    354   return FX_EnumGdiFonts;
    355 }
    356 
    357 #else  // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    358 
    359 namespace {
    360 
    361 const FX_CHAR* g_FontFolders[] = {
    362 #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
    363     "/usr/share/fonts", "/usr/share/X11/fonts/Type1",
    364     "/usr/share/X11/fonts/TTF", "/usr/local/share/fonts",
    365 #elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
    366     "~/Library/Fonts", "/Library/Fonts", "/System/Library/Fonts",
    367 #elif _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
    368     "/system/fonts",
    369 #endif
    370 };
    371 
    372 struct FX_BitCodePage {
    373   uint16_t wBit;
    374   uint16_t wCodePage;
    375 };
    376 
    377 const FX_BitCodePage g_Bit2CodePage[] = {
    378     {0, 1252}, {1, 1250}, {2, 1251}, {3, 1253},  {4, 1254}, {5, 1255},
    379     {6, 1256}, {7, 1257}, {8, 1258}, {9, 0},     {10, 0},   {11, 0},
    380     {12, 0},   {13, 0},   {14, 0},   {15, 0},    {16, 874}, {17, 932},
    381     {18, 936}, {19, 949}, {20, 950}, {21, 1361}, {22, 0},   {23, 0},
    382     {24, 0},   {25, 0},   {26, 0},   {27, 0},    {28, 0},   {29, 0},
    383     {30, 0},   {31, 0},   {32, 0},   {33, 0},    {34, 0},   {35, 0},
    384     {36, 0},   {37, 0},   {38, 0},   {39, 0},    {40, 0},   {41, 0},
    385     {42, 0},   {43, 0},   {44, 0},   {45, 0},    {46, 0},   {47, 0},
    386     {48, 869}, {49, 866}, {50, 865}, {51, 864},  {52, 863}, {53, 862},
    387     {54, 861}, {55, 860}, {56, 857}, {57, 855},  {58, 852}, {59, 775},
    388     {60, 737}, {61, 708}, {62, 850}, {63, 437},
    389 };
    390 
    391 uint16_t FX_GetCodePageBit(uint16_t wCodePage) {
    392   for (size_t i = 0; i < FX_ArraySize(g_Bit2CodePage); ++i) {
    393     if (g_Bit2CodePage[i].wCodePage == wCodePage)
    394       return g_Bit2CodePage[i].wBit;
    395   }
    396   return static_cast<uint16_t>(-1);
    397 }
    398 
    399 uint16_t FX_GetUnicodeBit(FX_WCHAR wcUnicode) {
    400   const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wcUnicode);
    401   return x ? x->wBitField : 999;
    402 }
    403 
    404 inline uint8_t GetUInt8(const uint8_t* p) {
    405   return p[0];
    406 }
    407 
    408 inline uint16_t GetUInt16(const uint8_t* p) {
    409   return static_cast<uint16_t>(p[0] << 8 | p[1]);
    410 }
    411 
    412 struct FX_BIT2CHARSET {
    413   uint16_t wBit;
    414   uint16_t wCharset;
    415 };
    416 
    417 const FX_BIT2CHARSET g_FX_Bit2Charset[4][16] = {
    418     {{1 << 0, FX_CHARSET_ANSI},
    419      {1 << 1, FX_CHARSET_MSWin_EasterEuropean},
    420      {1 << 2, FX_CHARSET_MSWin_Cyrillic},
    421      {1 << 3, FX_CHARSET_MSWin_Greek},
    422      {1 << 4, FX_CHARSET_MSWin_Turkish},
    423      {1 << 5, FX_CHARSET_MSWin_Hebrew},
    424      {1 << 6, FX_CHARSET_MSWin_Arabic},
    425      {1 << 7, FX_CHARSET_MSWin_Baltic},
    426      {1 << 8, FX_CHARSET_MSWin_Vietnamese},
    427      {1 << 9, FX_CHARSET_Default},
    428      {1 << 10, FX_CHARSET_Default},
    429      {1 << 11, FX_CHARSET_Default},
    430      {1 << 12, FX_CHARSET_Default},
    431      {1 << 13, FX_CHARSET_Default},
    432      {1 << 14, FX_CHARSET_Default},
    433      {1 << 15, FX_CHARSET_Default}},
    434     {{1 << 0, FX_CHARSET_Thai},
    435      {1 << 1, FX_CHARSET_ShiftJIS},
    436      {1 << 2, FX_CHARSET_ChineseSimplified},
    437      {1 << 3, FX_CHARSET_Korean},
    438      {1 << 4, FX_CHARSET_ChineseTriditional},
    439      {1 << 5, FX_CHARSET_Johab},
    440      {1 << 6, FX_CHARSET_Default},
    441      {1 << 7, FX_CHARSET_Default},
    442      {1 << 8, FX_CHARSET_Default},
    443      {1 << 9, FX_CHARSET_Default},
    444      {1 << 10, FX_CHARSET_Default},
    445      {1 << 11, FX_CHARSET_Default},
    446      {1 << 12, FX_CHARSET_Default},
    447      {1 << 13, FX_CHARSET_Default},
    448      {1 << 14, FX_CHARSET_OEM},
    449      {1 << 15, FX_CHARSET_Symbol}},
    450     {{1 << 0, FX_CHARSET_Default},
    451      {1 << 1, FX_CHARSET_Default},
    452      {1 << 2, FX_CHARSET_Default},
    453      {1 << 3, FX_CHARSET_Default},
    454      {1 << 4, FX_CHARSET_Default},
    455      {1 << 5, FX_CHARSET_Default},
    456      {1 << 6, FX_CHARSET_Default},
    457      {1 << 7, FX_CHARSET_Default},
    458      {1 << 8, FX_CHARSET_Default},
    459      {1 << 9, FX_CHARSET_Default},
    460      {1 << 10, FX_CHARSET_Default},
    461      {1 << 11, FX_CHARSET_Default},
    462      {1 << 12, FX_CHARSET_Default},
    463      {1 << 13, FX_CHARSET_Default},
    464      {1 << 14, FX_CHARSET_Default},
    465      {1 << 15, FX_CHARSET_Default}},
    466     {{1 << 0, FX_CHARSET_Default},
    467      {1 << 1, FX_CHARSET_Default},
    468      {1 << 2, FX_CHARSET_Default},
    469      {1 << 3, FX_CHARSET_Default},
    470      {1 << 4, FX_CHARSET_Default},
    471      {1 << 5, FX_CHARSET_Default},
    472      {1 << 6, FX_CHARSET_Default},
    473      {1 << 7, FX_CHARSET_Default},
    474      {1 << 8, FX_CHARSET_Default},
    475      {1 << 9, FX_CHARSET_Default},
    476      {1 << 10, FX_CHARSET_Default},
    477      {1 << 11, FX_CHARSET_Default},
    478      {1 << 12, FX_CHARSET_Default},
    479      {1 << 13, FX_CHARSET_Default},
    480      {1 << 14, FX_CHARSET_Default},
    481      {1 << 15, FX_CHARSET_US}}};
    482 
    483 }  // namespace
    484 
    485 CFX_FontDescriptor::CFX_FontDescriptor()
    486     : m_nFaceIndex(0), m_dwFontStyles(0), m_dwUsb(), m_dwCsb() {}
    487 
    488 CFX_FontDescriptor::~CFX_FontDescriptor() {}
    489 
    490 CFX_FontSourceEnum_File::CFX_FontSourceEnum_File() {
    491   for (size_t i = 0; i < FX_ArraySize(g_FontFolders); ++i)
    492     m_FolderPaths.push_back(g_FontFolders[i]);
    493 }
    494 
    495 CFX_FontSourceEnum_File::~CFX_FontSourceEnum_File() {}
    496 
    497 CFX_ByteString CFX_FontSourceEnum_File::GetNextFile() {
    498   FX_FileHandle* pCurHandle =
    499       !m_FolderQueue.empty() ? m_FolderQueue.back().pFileHandle : nullptr;
    500   if (!pCurHandle) {
    501     if (m_FolderPaths.empty())
    502       return "";
    503     pCurHandle = FX_OpenFolder(m_FolderPaths.back().c_str());
    504     FX_HandleParentPath hpp;
    505     hpp.pFileHandle = pCurHandle;
    506     hpp.bsParentPath = m_FolderPaths.back();
    507     m_FolderQueue.push_back(hpp);
    508   }
    509   CFX_ByteString bsName;
    510   bool bFolder;
    511   CFX_ByteString bsFolderSeparator =
    512       CFX_ByteString::FromUnicode(CFX_WideString(FX_GetFolderSeparator()));
    513   while (true) {
    514     if (!FX_GetNextFile(pCurHandle, &bsName, &bFolder)) {
    515       FX_CloseFolder(pCurHandle);
    516       if (!m_FolderQueue.empty())
    517         m_FolderQueue.pop_back();
    518       if (m_FolderQueue.empty()) {
    519         if (!m_FolderPaths.empty())
    520           m_FolderPaths.pop_back();
    521         return !m_FolderPaths.empty() ? GetNextFile() : "";
    522       }
    523       pCurHandle = m_FolderQueue.back().pFileHandle;
    524       continue;
    525     }
    526     if (bsName == "." || bsName == "..")
    527       continue;
    528     if (bFolder) {
    529       FX_HandleParentPath hpp;
    530       hpp.bsParentPath =
    531           m_FolderQueue.back().bsParentPath + bsFolderSeparator + bsName;
    532       hpp.pFileHandle = FX_OpenFolder(hpp.bsParentPath.c_str());
    533       if (!hpp.pFileHandle)
    534         continue;
    535       m_FolderQueue.push_back(hpp);
    536       pCurHandle = hpp.pFileHandle;
    537       continue;
    538     }
    539     bsName = m_FolderQueue.back().bsParentPath + bsFolderSeparator + bsName;
    540     break;
    541   }
    542   return bsName;
    543 }
    544 
    545 FX_POSITION CFX_FontSourceEnum_File::GetStartPosition() {
    546   m_wsNext = GetNextFile().UTF8Decode();
    547   if (m_wsNext.GetLength() == 0)
    548     return (FX_POSITION)0;
    549   return (FX_POSITION)-1;
    550 }
    551 
    552 CFX_RetainPtr<IFX_FileAccess> CFX_FontSourceEnum_File::GetNext(
    553     FX_POSITION& pos) {
    554   CFX_RetainPtr<IFX_FileAccess> pAccess =
    555       IFX_FileAccess::CreateDefault(m_wsNext.AsStringC());
    556   m_wsNext = GetNextFile().UTF8Decode();
    557   pos = m_wsNext.GetLength() != 0 ? pAccess.Get() : nullptr;
    558   return pAccess;
    559 }
    560 
    561 std::unique_ptr<CFGAS_FontMgr> CFGAS_FontMgr::Create(
    562     CFX_FontSourceEnum_File* pFontEnum) {
    563   if (!pFontEnum)
    564     return nullptr;
    565 
    566   auto pFontMgr = pdfium::MakeUnique<CFGAS_FontMgr>(pFontEnum);
    567   if (!pFontMgr->EnumFonts())
    568     return nullptr;
    569   return pFontMgr;
    570 }
    571 
    572 CFGAS_FontMgr::CFGAS_FontMgr(CFX_FontSourceEnum_File* pFontEnum)
    573     : m_pFontSource(pFontEnum) {}
    574 
    575 CFGAS_FontMgr::~CFGAS_FontMgr() {}
    576 
    577 bool CFGAS_FontMgr::EnumFontsFromFontMapper() {
    578   CFX_FontMapper* pFontMapper =
    579       CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper();
    580   if (!pFontMapper)
    581     return false;
    582 
    583   IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
    584   if (!pSystemFontInfo)
    585     return false;
    586 
    587   pSystemFontInfo->EnumFontList(pFontMapper);
    588   for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
    589     CFX_RetainPtr<IFX_SeekableReadStream> pFontStream =
    590         CreateFontStream(pFontMapper, pSystemFontInfo, i);
    591     if (!pFontStream)
    592       continue;
    593 
    594     CFX_WideString wsFaceName =
    595         CFX_WideString::FromLocal(pFontMapper->GetFaceName(i).c_str());
    596     RegisterFaces(pFontStream, &wsFaceName);
    597   }
    598   return !m_InstalledFonts.empty();
    599 }
    600 
    601 bool CFGAS_FontMgr::EnumFontsFromFiles() {
    602   CFX_GEModule::Get()->GetFontMgr()->InitFTLibrary();
    603   FX_POSITION pos = m_pFontSource->GetStartPosition();
    604   while (pos) {
    605     CFX_RetainPtr<IFX_FileAccess> pFontSource = m_pFontSource->GetNext(pos);
    606     CFX_RetainPtr<IFX_SeekableReadStream> pFontStream =
    607         pFontSource->CreateFileStream(FX_FILEMODE_ReadOnly);
    608     if (pFontStream)
    609       RegisterFaces(pFontStream, nullptr);
    610   }
    611   return !m_InstalledFonts.empty();
    612 }
    613 
    614 bool CFGAS_FontMgr::EnumFonts() {
    615   return EnumFontsFromFontMapper() || EnumFontsFromFiles();
    616 }
    617 
    618 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(
    619     const FX_WCHAR* pszFontFamily,
    620     uint32_t dwFontStyles,
    621     uint16_t wCodePage) {
    622   return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
    623 }
    624 
    625 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage(
    626     uint16_t wCodePage,
    627     uint32_t dwFontStyles,
    628     const FX_WCHAR* pszFontFamily) {
    629   CFX_ByteString bsHash;
    630   bsHash.Format("%d, %d", wCodePage, dwFontStyles);
    631   bsHash += FX_UTF8Encode(CFX_WideStringC(pszFontFamily));
    632   uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false);
    633   std::vector<CFX_RetainPtr<CFGAS_GEFont>>* pFontArray = &m_Hash2Fonts[dwHash];
    634   if (!pFontArray->empty())
    635     return (*pFontArray)[0];
    636 
    637   std::vector<CFX_FontDescriptorInfo>* sortedFontInfos =
    638       m_Hash2CandidateList[dwHash].get();
    639   if (!sortedFontInfos) {
    640     auto pNewFonts = pdfium::MakeUnique<std::vector<CFX_FontDescriptorInfo>>();
    641     sortedFontInfos = pNewFonts.get();
    642     MatchFonts(sortedFontInfos, wCodePage, dwFontStyles,
    643                CFX_WideString(pszFontFamily), 0);
    644     m_Hash2CandidateList[dwHash] = std::move(pNewFonts);
    645   }
    646   if (sortedFontInfos->empty())
    647     return nullptr;
    648 
    649   CFX_FontDescriptor* pDesc = (*sortedFontInfos)[0].pFont;
    650   CFX_RetainPtr<CFGAS_GEFont> pFont =
    651       LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
    652   if (!pFont)
    653     return nullptr;
    654 
    655   pFont->SetLogicalFontStyle(dwFontStyles);
    656   pFontArray->push_back(pFont);
    657   return pFont;
    658 }
    659 
    660 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicode(
    661     FX_WCHAR wUnicode,
    662     uint32_t dwFontStyles,
    663     const FX_WCHAR* pszFontFamily) {
    664   if (pdfium::ContainsKey(m_FailedUnicodesSet, wUnicode))
    665     return nullptr;
    666 
    667   const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wUnicode);
    668   uint16_t wCodePage = x ? x->wCodePage : 0xFFFF;
    669   uint16_t wBitField = x ? x->wBitField : 0x03E7;
    670   CFX_ByteString bsHash;
    671   if (wCodePage == 0xFFFF)
    672     bsHash.Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles);
    673   else
    674     bsHash.Format("%d, %d", wCodePage, dwFontStyles);
    675   bsHash += FX_UTF8Encode(CFX_WideStringC(pszFontFamily));
    676   uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false);
    677   std::vector<CFX_RetainPtr<CFGAS_GEFont>>* pFonts = &m_Hash2Fonts[dwHash];
    678   for (size_t i = 0; i < pFonts->size(); ++i) {
    679     if (VerifyUnicode((*pFonts)[i], wUnicode))
    680       return (*pFonts)[i];
    681   }
    682   std::vector<CFX_FontDescriptorInfo>* sortedFontInfos =
    683       m_Hash2CandidateList[dwHash].get();
    684   if (!sortedFontInfos) {
    685     auto pNewFonts = pdfium::MakeUnique<std::vector<CFX_FontDescriptorInfo>>();
    686     sortedFontInfos = pNewFonts.get();
    687     MatchFonts(sortedFontInfos, wCodePage, dwFontStyles,
    688                CFX_WideString(pszFontFamily), wUnicode);
    689     m_Hash2CandidateList[dwHash] = std::move(pNewFonts);
    690   }
    691   for (const auto& info : *sortedFontInfos) {
    692     CFX_FontDescriptor* pDesc = info.pFont;
    693     if (!VerifyUnicode(pDesc, wUnicode))
    694       continue;
    695     CFX_RetainPtr<CFGAS_GEFont> pFont =
    696         LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
    697     if (!pFont)
    698       continue;
    699     pFont->SetLogicalFontStyle(dwFontStyles);
    700     pFonts->push_back(pFont);
    701     return pFont;
    702   }
    703   if (!pszFontFamily)
    704     m_FailedUnicodesSet.insert(wUnicode);
    705   return nullptr;
    706 }
    707 
    708 bool CFGAS_FontMgr::VerifyUnicode(CFX_FontDescriptor* pDesc,
    709                                   FX_WCHAR wcUnicode) {
    710   CFX_RetainPtr<IFX_SeekableReadStream> pFileRead =
    711       CreateFontStream(pDesc->m_wsFaceName.UTF8Encode());
    712   if (!pFileRead)
    713     return false;
    714 
    715   FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex);
    716   FT_Error retCharmap = FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE);
    717   FT_Error retIndex = FXFT_Get_Char_Index(pFace, wcUnicode);
    718   if (!pFace)
    719     return false;
    720 
    721   if (FXFT_Get_Face_External_Stream(pFace))
    722     FXFT_Clear_Face_External_Stream(pFace);
    723 
    724   FXFT_Done_Face(pFace);
    725   return !retCharmap && retIndex;
    726 }
    727 
    728 bool CFGAS_FontMgr::VerifyUnicode(const CFX_RetainPtr<CFGAS_GEFont>& pFont,
    729                                   FX_WCHAR wcUnicode) {
    730   if (!pFont)
    731     return false;
    732 
    733   FXFT_Face pFace = pFont->GetDevFont()->GetFace();
    734   FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace);
    735   if (FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE) != 0)
    736     return false;
    737 
    738   if (FXFT_Get_Char_Index(pFace, wcUnicode) == 0) {
    739     FXFT_Set_Charmap(pFace, charmap);
    740     return false;
    741   }
    742   return true;
    743 }
    744 
    745 CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(
    746     const CFX_WideString& wsFaceName,
    747     int32_t iFaceIndex,
    748     int32_t* pFaceCount) {
    749   CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
    750   CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
    751   if (!pFontMapper)
    752     return nullptr;
    753 
    754   IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
    755   if (!pSystemFontInfo)
    756     return nullptr;
    757 
    758   CFX_RetainPtr<IFX_SeekableReadStream> pFontStream =
    759       CreateFontStream(wsFaceName.UTF8Encode());
    760   if (!pFontStream)
    761     return nullptr;
    762 
    763   auto pInternalFont = pdfium::MakeUnique<CFX_Font>();
    764   if (!pInternalFont->LoadFile(pFontStream, iFaceIndex))
    765     return nullptr;
    766 
    767   CFX_RetainPtr<CFGAS_GEFont> pFont =
    768       CFGAS_GEFont::LoadFont(std::move(pInternalFont), this);
    769   if (!pFont)
    770     return nullptr;
    771 
    772   m_IFXFont2FileRead[pFont] = pFontStream;
    773   if (pFaceCount)
    774     *pFaceCount = pFont->GetDevFont()->GetFace()->num_faces;
    775   return pFont;
    776 }
    777 
    778 extern "C" {
    779 
    780 unsigned long _ftStreamRead(FXFT_Stream stream,
    781                             unsigned long offset,
    782                             unsigned char* buffer,
    783                             unsigned long count) {
    784   if (count == 0)
    785     return 0;
    786 
    787   IFX_SeekableReadStream* pFile =
    788       static_cast<IFX_SeekableReadStream*>(stream->descriptor.pointer);
    789   if (!pFile->ReadBlock(buffer, offset, count))
    790     return 0;
    791 
    792   return count;
    793 }
    794 
    795 void _ftStreamClose(FXFT_Stream stream) {}
    796 
    797 };  // extern "C"
    798 
    799 FXFT_Face CFGAS_FontMgr::LoadFace(
    800     const CFX_RetainPtr<IFX_SeekableReadStream>& pFontStream,
    801     int32_t iFaceIndex) {
    802   if (!pFontStream)
    803     return nullptr;
    804 
    805   CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
    806   pFontMgr->InitFTLibrary();
    807 
    808   FXFT_Library library = pFontMgr->GetFTLibrary();
    809   if (!library)
    810     return nullptr;
    811 
    812   FXFT_Stream ftStream = FX_Alloc(FXFT_StreamRec, 1);
    813   FXSYS_memset(ftStream, 0, sizeof(FXFT_StreamRec));
    814   ftStream->base = nullptr;
    815   ftStream->descriptor.pointer = static_cast<void*>(pFontStream.Get());
    816   ftStream->pos = 0;
    817   ftStream->size = static_cast<unsigned long>(pFontStream->GetSize());
    818   ftStream->read = _ftStreamRead;
    819   ftStream->close = _ftStreamClose;
    820 
    821   FXFT_Open_Args ftArgs;
    822   FXSYS_memset(&ftArgs, 0, sizeof(FXFT_Open_Args));
    823   ftArgs.flags |= FT_OPEN_STREAM;
    824   ftArgs.stream = ftStream;
    825 
    826   FXFT_Face pFace = nullptr;
    827   if (FXFT_Open_Face(library, &ftArgs, iFaceIndex, &pFace)) {
    828     FX_Free(ftStream);
    829     return nullptr;
    830   }
    831 
    832   FXFT_Set_Pixel_Sizes(pFace, 0, 64);
    833   return pFace;
    834 }
    835 
    836 CFX_RetainPtr<IFX_SeekableReadStream> CFGAS_FontMgr::CreateFontStream(
    837     CFX_FontMapper* pFontMapper,
    838     IFX_SystemFontInfo* pSystemFontInfo,
    839     uint32_t index) {
    840   int iExact = 0;
    841   void* hFont =
    842       pSystemFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0,
    843                                pFontMapper->GetFaceName(index).c_str(), iExact);
    844   if (!hFont)
    845     return nullptr;
    846 
    847   uint32_t dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, nullptr, 0);
    848   if (dwFileSize == 0)
    849     return nullptr;
    850 
    851   uint8_t* pBuffer = FX_Alloc(uint8_t, dwFileSize + 1);
    852   dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, pBuffer, dwFileSize);
    853 
    854   return IFX_MemoryStream::Create(pBuffer, dwFileSize, true);
    855 }
    856 
    857 CFX_RetainPtr<IFX_SeekableReadStream> CFGAS_FontMgr::CreateFontStream(
    858     const CFX_ByteString& bsFaceName) {
    859   CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
    860   CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
    861   if (!pFontMapper)
    862     return nullptr;
    863 
    864   IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
    865   if (!pSystemFontInfo)
    866     return nullptr;
    867 
    868   pSystemFontInfo->EnumFontList(pFontMapper);
    869   for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
    870     if (pFontMapper->GetFaceName(i) == bsFaceName)
    871       return CreateFontStream(pFontMapper, pSystemFontInfo, i);
    872   }
    873   return nullptr;
    874 }
    875 
    876 void CFGAS_FontMgr::MatchFonts(
    877     std::vector<CFX_FontDescriptorInfo>* pMatchedFonts,
    878     uint16_t wCodePage,
    879     uint32_t dwFontStyles,
    880     const CFX_WideString& FontName,
    881     FX_WCHAR wcUnicode) {
    882   pMatchedFonts->clear();
    883   for (const auto& pFont : m_InstalledFonts) {
    884     int32_t nPenalty =
    885         CalcPenalty(pFont.get(), wCodePage, dwFontStyles, FontName, wcUnicode);
    886     if (nPenalty >= 0xffff)
    887       continue;
    888     pMatchedFonts->push_back({pFont.get(), nPenalty});
    889     if (pMatchedFonts->size() == 0xffff)
    890       break;
    891   }
    892   std::sort(pMatchedFonts->begin(), pMatchedFonts->end());
    893 }
    894 
    895 int32_t CFGAS_FontMgr::CalcPenalty(CFX_FontDescriptor* pInstalled,
    896                                    uint16_t wCodePage,
    897                                    uint32_t dwFontStyles,
    898                                    const CFX_WideString& FontName,
    899                                    FX_WCHAR wcUnicode) {
    900   int32_t nPenalty = 30000;
    901   if (FontName.GetLength() != 0) {
    902     if (FontName != pInstalled->m_wsFaceName) {
    903       size_t i;
    904       for (i = 0; i < pInstalled->m_wsFamilyNames.size(); ++i) {
    905         if (pInstalled->m_wsFamilyNames[i] == FontName)
    906           break;
    907       }
    908       if (i == pInstalled->m_wsFamilyNames.size())
    909         nPenalty += 0xFFFF;
    910       else
    911         nPenalty -= 28000;
    912     } else {
    913       nPenalty -= 30000;
    914     }
    915     if (30000 == nPenalty &&
    916         0 == IsPartName(pInstalled->m_wsFaceName, FontName)) {
    917       size_t i;
    918       for (i = 0; i < pInstalled->m_wsFamilyNames.size(); i++) {
    919         if (IsPartName(pInstalled->m_wsFamilyNames[i], FontName) != 0)
    920           break;
    921       }
    922       if (i == pInstalled->m_wsFamilyNames.size())
    923         nPenalty += 0xFFFF;
    924       else
    925         nPenalty -= 26000;
    926     } else {
    927       nPenalty -= 27000;
    928     }
    929   }
    930   uint32_t dwStyleMask = pInstalled->m_dwFontStyles ^ dwFontStyles;
    931   if (dwStyleMask & FX_FONTSTYLE_Bold)
    932     nPenalty += 4500;
    933   if (dwStyleMask & FX_FONTSTYLE_FixedPitch)
    934     nPenalty += 10000;
    935   if (dwStyleMask & FX_FONTSTYLE_Italic)
    936     nPenalty += 10000;
    937   if (dwStyleMask & FX_FONTSTYLE_Serif)
    938     nPenalty += 500;
    939   if (dwStyleMask & FX_FONTSTYLE_Symbolic)
    940     nPenalty += 0xFFFF;
    941   if (nPenalty >= 0xFFFF)
    942     return 0xFFFF;
    943 
    944   uint16_t wBit = (wCodePage == 0 || wCodePage == 0xFFFF)
    945                       ? static_cast<uint16_t>(-1)
    946                       : FX_GetCodePageBit(wCodePage);
    947   if (wBit != static_cast<uint16_t>(-1)) {
    948     ASSERT(wBit < 64);
    949     if ((pInstalled->m_dwCsb[wBit / 32] & (1 << (wBit % 32))) == 0)
    950       nPenalty += 0xFFFF;
    951     else
    952       nPenalty -= 60000;
    953   }
    954   wBit = (wcUnicode == 0 || wcUnicode == 0xFFFE) ? static_cast<uint16_t>(999)
    955                                                  : FX_GetUnicodeBit(wcUnicode);
    956   if (wBit != static_cast<uint16_t>(999)) {
    957     ASSERT(wBit < 128);
    958     if ((pInstalled->m_dwUsb[wBit / 32] & (1 << (wBit % 32))) == 0)
    959       nPenalty += 0xFFFF;
    960     else
    961       nPenalty -= 60000;
    962   }
    963   return nPenalty;
    964 }
    965 
    966 void CFGAS_FontMgr::RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pEFont) {
    967   if (!pEFont)
    968     return;
    969 
    970   m_IFXFont2FileRead.erase(pEFont);
    971 
    972   auto iter = m_Hash2Fonts.begin();
    973   while (iter != m_Hash2Fonts.end()) {
    974     auto old_iter = iter++;
    975     bool all_empty = true;
    976     for (size_t i = 0; i < old_iter->second.size(); i++) {
    977       if (old_iter->second[i] == pEFont)
    978         old_iter->second[i].Reset();
    979       else if (old_iter->second[i])
    980         all_empty = false;
    981     }
    982     if (all_empty)
    983       m_Hash2Fonts.erase(old_iter);
    984   }
    985 }
    986 
    987 void CFGAS_FontMgr::RegisterFace(FXFT_Face pFace,
    988                                  const CFX_WideString* pFaceName) {
    989   if ((pFace->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
    990     return;
    991 
    992   auto pFont = pdfium::MakeUnique<CFX_FontDescriptor>();
    993   pFont->m_dwFontStyles |= FXFT_Is_Face_Bold(pFace) ? FX_FONTSTYLE_Bold : 0;
    994   pFont->m_dwFontStyles |= FXFT_Is_Face_Italic(pFace) ? FX_FONTSTYLE_Italic : 0;
    995   pFont->m_dwFontStyles |= GetFlags(pFace);
    996 
    997   std::vector<uint16_t> charsets = GetCharsets(pFace);
    998   GetUSBCSB(pFace, pFont->m_dwUsb, pFont->m_dwCsb);
    999 
   1000   FT_ULong dwTag;
   1001   FT_ENC_TAG(dwTag, 'n', 'a', 'm', 'e');
   1002 
   1003   std::vector<uint8_t> table;
   1004   unsigned long nLength = 0;
   1005   unsigned int error = FXFT_Load_Sfnt_Table(pFace, dwTag, 0, nullptr, &nLength);
   1006   if (error == 0 && nLength != 0) {
   1007     table.resize(nLength);
   1008     if (FXFT_Load_Sfnt_Table(pFace, dwTag, 0, table.data(), nullptr))
   1009       table.clear();
   1010   }
   1011   GetNames(table.empty() ? nullptr : table.data(), pFont->m_wsFamilyNames);
   1012   pFont->m_wsFamilyNames.push_back(
   1013       CFX_ByteString(pFace->family_name).UTF8Decode());
   1014   pFont->m_wsFaceName =
   1015       pFaceName ? *pFaceName
   1016                 : CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(pFace));
   1017   pFont->m_nFaceIndex = pFace->face_index;
   1018   m_InstalledFonts.push_back(std::move(pFont));
   1019 }
   1020 
   1021 void CFGAS_FontMgr::RegisterFaces(
   1022     const CFX_RetainPtr<IFX_SeekableReadStream>& pFontStream,
   1023     const CFX_WideString* pFaceName) {
   1024   int32_t index = 0;
   1025   int32_t num_faces = 0;
   1026   do {
   1027     FXFT_Face pFace = LoadFace(pFontStream, index++);
   1028     if (!pFace)
   1029       continue;
   1030     // All faces keep number of faces. It can be retrieved from any one face.
   1031     if (num_faces == 0)
   1032       num_faces = pFace->num_faces;
   1033     RegisterFace(pFace, pFaceName);
   1034     if (FXFT_Get_Face_External_Stream(pFace))
   1035       FXFT_Clear_Face_External_Stream(pFace);
   1036     FXFT_Done_Face(pFace);
   1037   } while (index < num_faces);
   1038 }
   1039 
   1040 uint32_t CFGAS_FontMgr::GetFlags(FXFT_Face pFace) {
   1041   uint32_t flag = 0;
   1042   if (FT_IS_FIXED_WIDTH(pFace))
   1043     flag |= FX_FONTSTYLE_FixedPitch;
   1044   TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
   1045   if (!pOS2)
   1046     return flag;
   1047 
   1048   if (pOS2->ulCodePageRange1 & (1 << 31))
   1049     flag |= FX_FONTSTYLE_Symbolic;
   1050   if (pOS2->panose[0] == 2) {
   1051     uint8_t uSerif = pOS2->panose[1];
   1052     if ((uSerif > 1 && uSerif < 10) || uSerif > 13)
   1053       flag |= FX_FONTSTYLE_Serif;
   1054   }
   1055   return flag;
   1056 }
   1057 
   1058 void CFGAS_FontMgr::GetNames(const uint8_t* name_table,
   1059                              std::vector<CFX_WideString>& Names) {
   1060   if (!name_table)
   1061     return;
   1062 
   1063   uint8_t* lpTable = (uint8_t*)name_table;
   1064   CFX_WideString wsFamily;
   1065   uint8_t* sp = lpTable + 2;
   1066   uint8_t* lpNameRecord = lpTable + 6;
   1067   uint16_t nNameCount = GetUInt16(sp);
   1068   uint8_t* lpStr = lpTable + GetUInt16(sp + 2);
   1069   for (uint16_t j = 0; j < nNameCount; j++) {
   1070     uint16_t nNameID = GetUInt16(lpNameRecord + j * 12 + 6);
   1071     if (nNameID != 1)
   1072       continue;
   1073 
   1074     uint16_t nPlatformID = GetUInt16(lpNameRecord + j * 12 + 0);
   1075     uint16_t nNameLength = GetUInt16(lpNameRecord + j * 12 + 8);
   1076     uint16_t nNameOffset = GetUInt16(lpNameRecord + j * 12 + 10);
   1077     wsFamily.clear();
   1078     if (nPlatformID != 1) {
   1079       for (uint16_t k = 0; k < nNameLength / 2; k++) {
   1080         FX_WCHAR wcTemp = GetUInt16(lpStr + nNameOffset + k * 2);
   1081         wsFamily += wcTemp;
   1082       }
   1083       Names.push_back(wsFamily);
   1084       continue;
   1085     }
   1086     for (uint16_t k = 0; k < nNameLength; k++) {
   1087       FX_WCHAR wcTemp = GetUInt8(lpStr + nNameOffset + k);
   1088       wsFamily += wcTemp;
   1089     }
   1090     Names.push_back(wsFamily);
   1091   }
   1092 }
   1093 
   1094 std::vector<uint16_t> CFGAS_FontMgr::GetCharsets(FXFT_Face pFace) const {
   1095   std::vector<uint16_t> charsets;
   1096   TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
   1097   if (!pOS2) {
   1098     charsets.push_back(FX_CHARSET_Default);
   1099     return charsets;
   1100   }
   1101   uint16_t a[4] = {
   1102       pOS2->ulCodePageRange1 & 0xffff, (pOS2->ulCodePageRange1 >> 16) & 0xffff,
   1103       pOS2->ulCodePageRange2 & 0xffff, (pOS2->ulCodePageRange2 >> 16) & 0xffff};
   1104   for (int n = 0; n < 4; n++) {
   1105     for (int32_t i = 0; i < 16; i++) {
   1106       if ((a[n] & g_FX_Bit2Charset[n][i].wBit) != 0)
   1107         charsets.push_back(g_FX_Bit2Charset[n][i].wCharset);
   1108     }
   1109   }
   1110   return charsets;
   1111 }
   1112 
   1113 void CFGAS_FontMgr::GetUSBCSB(FXFT_Face pFace, uint32_t* USB, uint32_t* CSB) {
   1114   TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
   1115   if (!pOS2) {
   1116     USB[0] = 0;
   1117     USB[1] = 0;
   1118     USB[2] = 0;
   1119     USB[3] = 0;
   1120     CSB[0] = 0;
   1121     CSB[1] = 0;
   1122     return;
   1123   }
   1124   USB[0] = pOS2->ulUnicodeRange1;
   1125   USB[1] = pOS2->ulUnicodeRange2;
   1126   USB[2] = pOS2->ulUnicodeRange3;
   1127   USB[3] = pOS2->ulUnicodeRange4;
   1128   CSB[0] = pOS2->ulCodePageRange1;
   1129   CSB[1] = pOS2->ulCodePageRange2;
   1130 }
   1131 
   1132 int32_t CFGAS_FontMgr::IsPartName(const CFX_WideString& Name1,
   1133                                   const CFX_WideString& Name2) {
   1134   if (Name1.Find(Name2.c_str()) != -1)
   1135     return 1;
   1136   return 0;
   1137 }
   1138 
   1139 #endif  // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
   1140