CFGAS_GEFont* CFGAS_FontMgr::LoadFont(const FX_WCHAR* pszFontFamily,
                                      uint32_t dwFontStyles,
                                      uint16_t wCodePage) {
  uint32_t dwHash =
      FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage);
  CFGAS_GEFont* pFont = nullptr;
  if (m_FamilyFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont))
    return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : nullptr;
  FX_FONTDESCRIPTOR const* pFD =
      FindFont(pszFontFamily, dwFontStyles, true, wCodePage);
  if (!pFD)
    pFD = FindFont(pszFontFamily, dwFontStyles, false, wCodePage);
  if (!pFD)
    return nullptr;

  if (wCodePage == 0xFFFF)
    wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
  pFont =
      CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
  if (!pFont)
    return nullptr;

  m_Fonts.Add(pFont);
  m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
  dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
  m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
  return LoadFont(pFont, dwFontStyles, wCodePage);
}
CFGAS_GEFont* CFGAS_StdFontMgrImp::GetDefFontByCodePage(
    uint16_t wCodePage,
    uint32_t dwFontStyles,
    const FX_WCHAR* pszFontFamily) {
  uint32_t dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
  CFGAS_GEFont* pFont = nullptr;
  if (m_CPFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
    return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : nullptr;
  }
  FX_FONTDESCRIPTOR const* pFD =
      FindFont(pszFontFamily, dwFontStyles, TRUE, wCodePage);
  if (!pFD)
    pFD = FindFont(nullptr, dwFontStyles, TRUE, wCodePage);
  if (!pFD)
    pFD = FindFont(nullptr, dwFontStyles, FALSE, wCodePage);
  if (!pFD)
    return nullptr;

  pFont =
      CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
  if (pFont) {
    m_Fonts.Add(pFont);
    m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
    dwHash = FGAS_GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage);
    m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
    return LoadFont(pFont, dwFontStyles, wCodePage);
  }
  return nullptr;
}
CFGAS_GEFont* CFGAS_StdFontMgrImp::GetDefFontByUnicode(
    FX_WCHAR wUnicode,
    uint32_t dwFontStyles,
    const FX_WCHAR* pszFontFamily) {
  const FGAS_FONTUSB* pRet = FGAS_GetUnicodeBitField(wUnicode);
  if (pRet->wBitField == 999)
    return nullptr;

  uint32_t dwHash =
      FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, pRet->wBitField);
  CFGAS_GEFont* pFont = nullptr;
  if (m_UnicodeFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont))
    return pFont ? LoadFont(pFont, dwFontStyles, pRet->wCodePage) : nullptr;

  FX_FONTDESCRIPTOR const* pFD =
      FindFont(pszFontFamily, dwFontStyles, FALSE, pRet->wCodePage,
               pRet->wBitField, wUnicode);
  if (!pFD && pszFontFamily) {
    pFD = FindFont(nullptr, dwFontStyles, FALSE, pRet->wCodePage,
                   pRet->wBitField, wUnicode);
  }
  if (!pFD)
    return nullptr;

  uint16_t wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
  const FX_WCHAR* pFontFace = pFD->wsFontFace;
  pFont = CFGAS_GEFont::LoadFont(pFontFace, dwFontStyles, wCodePage, this);
  if (pFont) {
    m_Fonts.Add(pFont);
    m_UnicodeFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
    dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
    m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
    dwHash = FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage);
    m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
    return LoadFont(pFont, dwFontStyles, wCodePage);
  }
  return nullptr;
}