Revert "Make CFX_FontMgr member variables private."
[pdfium.git] / core / src / fxge / ge / fx_ge_fontmap.cpp
index d4416d9..e88791a 100644 (file)
@@ -8,10 +8,33 @@
 
 #include "../../../include/fxge/fx_ge.h"
 #include "../../../include/fxge/fx_freetype.h"
+#include "../fontdata/chromefontdata/chromefontdata.h"
 #include "text_int.h"
+
 #define GET_TT_SHORT(w) (FX_WORD)(((w)[0] << 8) | (w)[1])
 #define GET_TT_LONG(w) \
   (FX_DWORD)(((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3])
+
+namespace {
+
+CFX_ByteString KeyNameFromFace(const CFX_ByteString& face_name,
+                               int weight,
+                               FX_BOOL bItalic) {
+  CFX_ByteString key(face_name);
+  key += ',';
+  key += CFX_ByteString::FormatInteger(weight);
+  key += bItalic ? 'I' : 'N';
+  return key;
+}
+
+CFX_ByteString KeyNameFromSize(int ttc_size, FX_DWORD checksum) {
+  CFX_ByteString key;
+  key.Format("%d:%d", ttc_size, checksum);
+  return key;
+}
+
+}  // namespace
+
 CFX_SubstFont::CFX_SubstFont() {
   m_ExtHandle = NULL;
   m_Charset = 0;
@@ -33,9 +56,7 @@ CTTFontDesc::~CTTFontDesc() {
         FXFT_Done_Face(m_TTCFace.m_pFaces[i]);
       }
   }
-  if (m_pFontData) {
-    FX_Free(m_pFontData);
-  }
+  FX_Free(m_pFontData);
 }
 FX_BOOL CTTFontDesc::ReleaseFace(FXFT_Face face) {
   if (m_Type == 1) {
@@ -76,14 +97,10 @@ void CFX_FontMgr::InitFTLibrary() {
   }
 }
 void CFX_FontMgr::FreeCache() {
-  FX_POSITION pos = m_FaceMap.GetStartPosition();
-  while (pos) {
-    CFX_ByteString Key;
-    CTTFontDesc* face;
-    m_FaceMap.GetNextAssoc(pos, Key, (void*&)face);
-    delete face;
-  }
-  m_FaceMap.RemoveAll();
+  for (const auto& pair : m_FaceMap) {
+    delete pair.second;
+  }
+  m_FaceMap.clear();
 }
 void CFX_FontMgr::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) {
   m_pBuiltinMapper->SetSystemFontInfo(pFontInfo);
@@ -105,18 +122,14 @@ FXFT_Face CFX_FontMgr::GetCachedFace(const CFX_ByteString& face_name,
                                      int weight,
                                      FX_BOOL bItalic,
                                      uint8_t*& pFontData) {
-  CFX_ByteString key(face_name);
-  key += ',';
-  key += CFX_ByteString::FormatInteger(weight);
-  key += bItalic ? 'I' : 'N';
-  CTTFontDesc* pFontDesc = NULL;
-  m_FaceMap.Lookup(key, (void*&)pFontDesc);
-  if (pFontDesc) {
-    pFontData = pFontDesc->m_pFontData;
-    pFontDesc->m_RefCount++;
-    return pFontDesc->m_SingleFace.m_pFace;
-  }
-  return NULL;
+  auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic));
+  if (it == m_FaceMap.end())
+    return nullptr;
+
+  CTTFontDesc* pFontDesc = it->second;
+  pFontData = pFontDesc->m_pFontData;
+  pFontDesc->m_RefCount++;
+  return pFontDesc->m_SingleFace.m_pFace;
 }
 FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name,
                                      int weight,
@@ -147,11 +160,7 @@ FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name,
     delete pFontDesc;
     return NULL;
   }
-  CFX_ByteString key(face_name);
-  key += ',';
-  key += CFX_ByteString::FormatInteger(weight);
-  key += bItalic ? 'I' : 'N';
-  m_FaceMap.SetAt(key, pFontDesc);
+  m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = pFontDesc;
   return pFontDesc->m_SingleFace.m_pFace;
 }
 const FX_CHAR* const g_Base14FontNames[14] = {
@@ -170,7 +179,7 @@ const FX_CHAR* const g_Base14FontNames[14] = {
     "Symbol",
     "ZapfDingbats",
 };
-const struct _AltFontName {
+const struct AltFontName {
   const FX_CHAR* m_pName;
   int m_Index;
 } g_AltFontNames[] = {
@@ -266,20 +275,10 @@ const struct _AltFontName {
 };
 extern "C" {
 static int compareString(const void* key, const void* element) {
-  return FXSYS_stricmp((const FX_CHAR*)key, ((_AltFontName*)element)->m_pName);
+  return FXSYS_stricmp((const FX_CHAR*)key, ((AltFontName*)element)->m_pName);
 }
 }
-int _PDF_GetStandardFontName(CFX_ByteString& name) {
-  _AltFontName* found =
-      (_AltFontName*)FXSYS_bsearch(name.c_str(), g_AltFontNames,
-                                   sizeof g_AltFontNames / sizeof(_AltFontName),
-                                   sizeof(_AltFontName), compareString);
-  if (found == NULL) {
-    return -1;
-  }
-  name = g_Base14FontNames[found->m_Index];
-  return found->m_Index;
-}
+
 int GetTTCIndex(const uint8_t* pFontData,
                 FX_DWORD ttc_size,
                 FX_DWORD font_offset) {
@@ -304,17 +303,15 @@ FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size,
                                         FX_DWORD checksum,
                                         int font_offset,
                                         uint8_t*& pFontData) {
-  CFX_ByteString key;
-  key.Format("%d:%d", ttc_size, checksum);
-  CTTFontDesc* pFontDesc = NULL;
-  m_FaceMap.Lookup(key, (void*&)pFontDesc);
-  if (pFontDesc == NULL) {
-    return NULL;
-  }
+  auto it = m_FaceMap.find(KeyNameFromSize(ttc_size, checksum));
+  if (it == m_FaceMap.end())
+    return nullptr;
+
+  CTTFontDesc* pFontDesc = it->second;
   pFontData = pFontDesc->m_pFontData;
   pFontDesc->m_RefCount++;
   int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
-  if (pFontDesc->m_TTCFace.m_pFaces[face_index] == NULL) {
+  if (!pFontDesc->m_TTCFace.m_pFaces[face_index]) {
     pFontDesc->m_TTCFace.m_pFaces[face_index] =
         GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
   }
@@ -325,8 +322,6 @@ FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size,
                                         uint8_t* pData,
                                         FX_DWORD size,
                                         int font_offset) {
-  CFX_ByteString key;
-  key.Format("%d:%d", ttc_size, checksum);
   CTTFontDesc* pFontDesc = new CTTFontDesc;
   pFontDesc->m_Type = 2;
   pFontDesc->m_pFontData = pData;
@@ -334,8 +329,7 @@ FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size,
     pFontDesc->m_TTCFace.m_pFaces[i] = NULL;
   }
   pFontDesc->m_RefCount++;
-  key.Format("%d:%d", ttc_size, checksum);
-  m_FaceMap.SetAt(key, pFontDesc);
+  m_FaceMap[KeyNameFromSize(ttc_size, checksum)] = pFontDesc;
   int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
   pFontDesc->m_TTCFace.m_pFaces[face_index] =
       GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
@@ -378,37 +372,17 @@ FXFT_Face CFX_FontMgr::GetFileFace(const FX_CHAR* filename, int face_index) {
   return face;
 }
 void CFX_FontMgr::ReleaseFace(FXFT_Face face) {
-  if (face == NULL) {
+  if (!face) {
     return;
   }
-  FX_POSITION pos = m_FaceMap.GetStartPosition();
-  while (pos) {
-    CFX_ByteString Key;
-    CTTFontDesc* ttface;
-    m_FaceMap.GetNextAssoc(pos, Key, (void*&)ttface);
-    if (ttface->ReleaseFace(face)) {
-      m_FaceMap.RemoveKey(Key);
+  auto it = m_FaceMap.begin();
+  while (it != m_FaceMap.end()) {
+    auto temp = it++;
+    if (temp->second->ReleaseFace(face)) {
+      m_FaceMap.erase(temp);
     }
   }
 }
-extern "C" {
-extern const unsigned char g_FoxitFixedItalicFontData[18746];
-extern const unsigned char g_FoxitFixedFontData[17597];
-extern const unsigned char g_FoxitSansItalicFontData[16339];
-extern const unsigned char g_FoxitSansFontData[15025];
-extern const unsigned char g_FoxitSerifItalicFontData[21227];
-extern const unsigned char g_FoxitSerifFontData[19469];
-extern const unsigned char g_FoxitFixedBoldItalicFontData[19151];
-extern const unsigned char g_FoxitFixedBoldFontData[18055];
-extern const unsigned char g_FoxitSansBoldItalicFontData[16418];
-extern const unsigned char g_FoxitSansBoldFontData[16344];
-extern const unsigned char g_FoxitSerifBoldItalicFontData[20733];
-extern const unsigned char g_FoxitSerifBoldFontData[19395];
-extern const unsigned char g_FoxitSymbolFontData[16729];
-extern const unsigned char g_FoxitDingbatsFontData[29513];
-extern const unsigned char g_FoxitSerifMMFontData[113417];
-extern const unsigned char g_FoxitSansMMFontData[66919];
-};
 const FoxitFonts g_FoxitFonts[14] = {
     {g_FoxitFixedFontData, 17597},
     {g_FoxitFixedBoldFontData, 18055},
@@ -425,11 +399,6 @@ const FoxitFonts g_FoxitFonts[14] = {
     {g_FoxitSymbolFontData, 16729},
     {g_FoxitDingbatsFontData, 29513},
 };
-void _FPDFAPI_GetInternalFontData(int id,
-                                  const uint8_t*& data,
-                                  FX_DWORD& size) {
-  CFX_GEModule::Get()->GetFontMgr()->GetStandardFont(data, size, id);
-}
 FX_BOOL CFX_FontMgr::GetStandardFont(const uint8_t*& pFontData,
                                      FX_DWORD& size,
                                      int index) {
@@ -486,7 +455,7 @@ void CFX_FontMapper::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) {
   m_pFontInfo = pFontInfo;
 }
 static CFX_ByteString _TT_NormalizeName(const FX_CHAR* family) {
-  CFX_ByteString norm(family, -1);
+  CFX_ByteString norm(family);
   norm.Remove(' ');
   norm.Remove('-');
   norm.Remove(',');
@@ -497,8 +466,7 @@ static CFX_ByteString _TT_NormalizeName(const FX_CHAR* family) {
   norm.MakeLower();
   return norm;
 }
-CFX_ByteString _FPDF_GetNameFromTT(const uint8_t* name_table,
-                                   FX_DWORD name_id) {
+CFX_ByteString GetNameFromTT(const uint8_t* name_table, FX_DWORD name_id) {
   const uint8_t* ptr = name_table + 2;
   int name_count = GET_TT_SHORT(ptr);
   int string_offset = GET_TT_SHORT(ptr + 2);
@@ -559,14 +527,14 @@ CFX_ByteString _FPDF_LoadTableFromTTStreamFile(IFX_FileStream* pFile,
 }
 CFX_ByteString CFX_FontMapper::GetPSNameFromTT(void* hFont) {
   if (m_pFontInfo == NULL) {
-    CFX_ByteString();
+    return CFX_ByteString();
   }
   CFX_ByteString result;
   FX_DWORD size = m_pFontInfo->GetFontData(hFont, 0x6e616d65, NULL, 0);
   if (size) {
     uint8_t* buffer = FX_Alloc(uint8_t, size);
     m_pFontInfo->GetFontData(hFont, 0x6e616d65, buffer, size);
-    result = _FPDF_GetNameFromTT(buffer, 6);
+    result = GetNameFromTT(buffer, 6);
     FX_Free(buffer);
   }
   return result;
@@ -868,7 +836,7 @@ FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name,
       SubstName = name.Mid(1);
     }
   }
-  _PDF_GetStandardFontName(SubstName);
+  PDF_GetStandardFontName(&SubstName);
   if (SubstName == FX_BSTRC("Symbol") && !bTrueType) {
     pSubstFont->m_Family = "Chrome Symbol";
     pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET;
@@ -902,7 +870,7 @@ FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name,
   int find = SubstName.Find(FX_BSTRC(","), 0);
   if (find >= 0) {
     family = SubstName.Left(find);
-    _PDF_GetStandardFontName(family);
+    PDF_GetStandardFontName(&family);
     style = SubstName.Mid(find + 1);
     bHasComma = TRUE;
   } else {
@@ -1265,10 +1233,6 @@ CFontFileFaceInfo::~CFontFileFaceInfo() {
   }
   m_Face = NULL;
 }
-extern FX_BOOL _LoadFile(FXFT_Library library,
-                         FXFT_Face* Face,
-                         IFX_FileRead* pFile,
-                         FXFT_Stream* stream);
 #if _FX_OS_ == _FX_ANDROID_
 IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault(const char** pUnused) {
   return NULL;
@@ -1276,12 +1240,8 @@ IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault(const char** pUnused) {
 #endif
 CFX_FolderFontInfo::CFX_FolderFontInfo() {}
 CFX_FolderFontInfo::~CFX_FolderFontInfo() {
-  FX_POSITION pos = m_FontList.GetStartPosition();
-  while (pos) {
-    CFX_ByteString key;
-    void* value;
-    m_FontList.GetNextAssoc(pos, key, value);
-    delete (CFX_FontFaceInfo*)value;
+  for (const auto& pair : m_FontList) {
+    delete pair.second;
   }
 }
 void CFX_FolderFontInfo::AddPath(const CFX_ByteStringC& path) {
@@ -1386,13 +1346,12 @@ void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path,
   }
   CFX_ByteString names =
       _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x6e616d65);
-  CFX_ByteString facename = _FPDF_GetNameFromTT(names, 1);
-  CFX_ByteString style = _FPDF_GetNameFromTT(names, 2);
+  CFX_ByteString facename = GetNameFromTT(names, 1);
+  CFX_ByteString style = GetNameFromTT(names, 2);
   if (style != "Regular") {
     facename += " " + style;
   }
-  void* p;
-  if (m_FontList.Lookup(facename, p)) {
+  if (m_FontList.find(facename) != m_FontList.end()) {
     return;
   }
   CFX_FontFaceInfo* pInfo =
@@ -1436,7 +1395,106 @@ void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path,
   if (facename.Find(FX_BSTRC("Serif")) > -1) {
     pInfo->m_Styles |= FXFONT_SERIF;
   }
-  m_FontList.SetAt(facename, pInfo);
+  m_FontList[facename] = pInfo;
+}
+static const struct {
+  const FX_CHAR* m_pName;
+  const FX_CHAR* m_pSubstName;
+} Base14Substs[] = {
+    {"Courier", "Courier New"},
+    {"Courier-Bold", "Courier New Bold"},
+    {"Courier-BoldOblique", "Courier New Bold Italic"},
+    {"Courier-Oblique", "Courier New Italic"},
+    {"Helvetica", "Arial"},
+    {"Helvetica-Bold", "Arial Bold"},
+    {"Helvetica-BoldOblique", "Arial Bold Italic"},
+    {"Helvetica-Oblique", "Arial Italic"},
+    {"Times-Roman", "Times New Roman"},
+    {"Times-Bold", "Times New Roman Bold"},
+    {"Times-BoldItalic", "Times New Roman Bold Italic"},
+    {"Times-Italic", "Times New Roman Italic"},
+};
+void* CFX_FolderFontInfo::GetSubstFont(const CFX_ByteString& face) {
+  for (size_t iBaseFont = 0; iBaseFont < FX_ArraySize(Base14Substs);
+       iBaseFont++) {
+    if (face == Base14Substs[iBaseFont].m_pName) {
+      return GetFont(Base14Substs[iBaseFont].m_pSubstName);
+    }
+  }
+  return nullptr;
+}
+static FX_DWORD _GetCharset(int charset) {
+  switch (charset) {
+    case FXFONT_SHIFTJIS_CHARSET:
+      return CHARSET_FLAG_SHIFTJIS;
+    case FXFONT_GB2312_CHARSET:
+      return CHARSET_FLAG_GB;
+    case FXFONT_CHINESEBIG5_CHARSET:
+      return CHARSET_FLAG_BIG5;
+    case FXFONT_HANGEUL_CHARSET:
+      return CHARSET_FLAG_KOREAN;
+    case FXFONT_SYMBOL_CHARSET:
+      return CHARSET_FLAG_SYMBOL;
+    case FXFONT_ANSI_CHARSET:
+      return CHARSET_FLAG_ANSI;
+    default:
+      break;
+  }
+  return 0;
+}
+static int32_t _GetSimilarValue(int weight,
+                                FX_BOOL bItalic,
+                                int pitch_family,
+                                FX_DWORD style) {
+  int32_t iSimilarValue = 0;
+  if ((style & FXFONT_BOLD) == (weight > 400)) {
+    iSimilarValue += 16;
+  }
+  if ((style & FXFONT_ITALIC) == bItalic) {
+    iSimilarValue += 16;
+  }
+  if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) {
+    iSimilarValue += 16;
+  }
+  if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) {
+    iSimilarValue += 8;
+  }
+  if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) {
+    iSimilarValue += 8;
+  }
+  return iSimilarValue;
+}
+void* CFX_FolderFontInfo::FindFont(int weight,
+                                   FX_BOOL bItalic,
+                                   int charset,
+                                   int pitch_family,
+                                   const FX_CHAR* family,
+                                   FX_BOOL bMatchName) {
+  CFX_FontFaceInfo* pFind = nullptr;
+  if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) {
+    return GetFont("Courier New");
+  }
+  FX_DWORD charset_flag = _GetCharset(charset);
+  int32_t iBestSimilar = 0;
+  for (const auto& it : m_FontList) {
+    const CFX_ByteString& bsName = it.first;
+    CFX_FontFaceInfo* pFont = it.second;
+    if (!(pFont->m_Charsets & charset_flag) &&
+        charset != FXFONT_DEFAULT_CHARSET) {
+      continue;
+    }
+    int32_t index = bsName.Find(family);
+    if (bMatchName && index < 0) {
+      continue;
+    }
+    int32_t iSimilarValue =
+        _GetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles);
+    if (iSimilarValue > iBestSimilar) {
+      iBestSimilar = iSimilarValue;
+      pFind = pFont;
+    }
+  }
+  return pFind;
 }
 void* CFX_FolderFontInfo::MapFont(int weight,
                                   FX_BOOL bItalic,
@@ -1447,11 +1505,8 @@ void* CFX_FolderFontInfo::MapFont(int weight,
   return NULL;
 }
 void* CFX_FolderFontInfo::GetFont(const FX_CHAR* face) {
-  void* p;
-  if (!m_FontList.Lookup(face, p)) {
-    return NULL;
-  }
-  return p;
+  auto it = m_FontList.find(face);
+  return it != m_FontList.end() ? it->second : nullptr;
 }
 FX_DWORD CFX_FolderFontInfo::GetFontData(void* hFont,
                                          FX_DWORD table,
@@ -1469,13 +1524,11 @@ FX_DWORD CFX_FolderFontInfo::GetFontData(void* hFont,
     }
   }
   FX_DWORD datasize = 0;
-  FX_DWORD offset;
+  FX_DWORD offset = 0;
   if (table == 0) {
     datasize = pFont->m_FontOffset ? 0 : pFont->m_FileSize;
-    offset = 0;
   } else if (table == 0x74746366) {
     datasize = pFont->m_FontOffset ? pFont->m_FileSize : 0;
-    offset = 0;
   } else {
     FX_DWORD nTables = pFont->m_FontTables.GetLength() / 16;
     for (FX_DWORD i = 0; i < nTables; i++) {
@@ -1507,3 +1560,14 @@ FX_BOOL CFX_FolderFontInfo::GetFaceName(void* hFont, CFX_ByteString& name) {
 FX_BOOL CFX_FolderFontInfo::GetFontCharset(void* hFont, int& charset) {
   return FALSE;
 }
+
+int PDF_GetStandardFontName(CFX_ByteString* name) {
+  AltFontName* found = static_cast<AltFontName*>(
+      FXSYS_bsearch(name->c_str(), g_AltFontNames, FX_ArraySize(g_AltFontNames),
+                    sizeof(AltFontName), compareString));
+  if (!found)
+    return -1;
+
+  *name = g_Base14FontNames[found->m_Index];
+  return found->m_Index;
+}