Encapsulate FT_Select_Charmap() inside CFX_Face

Instead of directly calling this FreeType function, call it via CFX_Face
instead. Also remove FXFT_Select_Charmap().

Bug: pdfium:2037
Change-Id: Ifdcd6b2517d1d1f343a56fd7cda2f986565d81d7
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/114772
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index 932a79d..9d494b7 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -194,7 +194,7 @@
 
 #endif  // !BUILDFLAG(IS_WIN)
 
-void FT_UseCIDCharmap(FXFT_FaceRec* face, CIDCoding coding) {
+void FT_UseCIDCharmap(const RetainPtr<CFX_Face>& face, CIDCoding coding) {
   fxge::FontEncoding encoding;
   switch (coding) {
     case CIDCoding::kGB:
@@ -212,12 +212,14 @@
     default:
       encoding = fxge::FontEncoding::kUnicode;
   }
-  int err = FXFT_Select_Charmap(face, encoding);
-  if (err)
-    err = FXFT_Select_Charmap(
-        face, static_cast<FT_Encoding>(fxge::FontEncoding::kUnicode));
-  if (err && face->charmaps)
-    FT_Set_Charmap(face, face->charmaps[0]);
+  bool result = face->SelectCharMap(encoding);
+  if (!result) {
+    result = face->SelectCharMap(fxge::FontEncoding::kUnicode);
+  }
+  FXFT_FaceRec* face_rec = face->GetRec();
+  if (!result && face_rec->charmaps) {
+    FT_Set_Charmap(face_rec, face_rec->charmaps[0]);
+  }
 }
 
 bool IsMetricForCID(const int* pEntry, uint16_t cid) {
@@ -470,11 +472,9 @@
   }
   if (m_Font.GetFaceRec()) {
     if (m_FontType == CIDFontType::kType1)
-      FXFT_Select_Charmap(
-          m_Font.GetFaceRec(),
-          static_cast<FT_Encoding>(fxge::FontEncoding::kUnicode));
+      m_Font.GetFace()->SelectCharMap(fxge::FontEncoding::kUnicode);
     else
-      FT_UseCIDCharmap(m_Font.GetFaceRec(), m_pCMap->GetCoding());
+      FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->GetCoding());
   }
   m_DefaultWidth = pCIDFontDict->GetIntegerFor("DW", 1000);
   RetainPtr<const CPDF_Array> pWidthArray = pCIDFontDict->GetArrayFor("W");
@@ -717,14 +717,14 @@
           unicode = unicode_str[0];
       }
     }
-    FXFT_FaceRec* face = m_Font.GetFaceRec();
+    FXFT_FaceRec* face_rec = m_Font.GetFaceRec();
     if (unicode == 0) {
       if (!m_bAdobeCourierStd)
         return charcode ? static_cast<int>(charcode) : -1;
 
       charcode += 31;
-      bool bMSUnicode = UseTTCharmapMSUnicode(face);
-      bool bMacRoman = !bMSUnicode && UseTTCharmapMacRoman(face);
+      bool bMSUnicode = UseTTCharmapMSUnicode(face_rec);
+      bool bMacRoman = !bMSUnicode && UseTTCharmapMacRoman(face_rec);
       FontEncoding base_encoding = FontEncoding::kStandard;
       if (bMSUnicode)
         base_encoding = FontEncoding::kWinAnsi;
@@ -741,16 +741,16 @@
         return charcode ? static_cast<int>(charcode) : -1;
 
       if (base_encoding == FontEncoding::kStandard)
-        return FT_Get_Char_Index(face, name_unicode);
+        return FT_Get_Char_Index(face_rec, name_unicode);
 
       if (base_encoding == FontEncoding::kWinAnsi) {
-        index = FT_Get_Char_Index(face, name_unicode);
+        index = FT_Get_Char_Index(face_rec, name_unicode);
       } else {
         DCHECK_EQ(base_encoding, FontEncoding::kMacRoman);
         uint32_t maccode = CharCodeFromUnicodeForEncoding(
             fxge::FontEncoding::kAppleRoman, name_unicode);
-        index = maccode ? FT_Get_Char_Index(face, maccode)
-                        : FT_Get_Name_Index(face, name);
+        index = maccode ? FT_Get_Char_Index(face_rec, maccode)
+                        : FT_Get_Name_Index(face_rec, name);
       }
       if (index == 0 || index == 0xffff)
         return charcode ? static_cast<int>(charcode) : -1;
@@ -765,30 +765,29 @@
 #endif
       }
     }
-    if (!face)
+    if (!face_rec) {
       return unicode;
+    }
 
-    int err = FXFT_Select_Charmap(
-        face, static_cast<FT_Encoding>(fxge::FontEncoding::kUnicode));
-    if (err) {
+    if (!m_Font.GetFace()->SelectCharMap(fxge::FontEncoding::kUnicode)) {
       int i;
-      for (i = 0; i < face->num_charmaps; i++) {
+      for (i = 0; i < face_rec->num_charmaps; i++) {
         uint32_t ret = CharCodeFromUnicodeForEncoding(
             static_cast<fxge::FontEncoding>(
-                FXFT_Get_Charmap_Encoding(face->charmaps[i])),
+                FXFT_Get_Charmap_Encoding(face_rec->charmaps[i])),
             static_cast<wchar_t>(charcode));
         if (ret == 0)
           continue;
-        FT_Set_Charmap(face, face->charmaps[i]);
+        FT_Set_Charmap(face_rec, face_rec->charmaps[i]);
         unicode = static_cast<wchar_t>(ret);
         break;
       }
-      if (i == face->num_charmaps && i) {
-        FT_Set_Charmap(face, face->charmaps[0]);
+      if (i == face_rec->num_charmaps && i) {
+        FT_Set_Charmap(face_rec, face_rec->charmaps[0]);
         unicode = static_cast<wchar_t>(charcode);
       }
     }
-    if (face->charmap) {
+    if (face_rec->charmap) {
       int index = GetGlyphIndex(unicode, pVertGlyph);
       return index != 0 ? index : -1;
     }
diff --git a/core/fpdfapi/font/cpdf_truetypefont.cpp b/core/fpdfapi/font/cpdf_truetypefont.cpp
index e090a25..e2c9dee 100644
--- a/core/fpdfapi/font/cpdf_truetypefont.cpp
+++ b/core/fpdfapi/font/cpdf_truetypefont.cpp
@@ -144,8 +144,7 @@
     if (m_pFontFile || HasAnyGlyphIndex())
       return;
   }
-  if (FXFT_Select_Charmap(
-          face, static_cast<FT_Encoding>(fxge::FontEncoding::kUnicode)) == 0) {
+  if (m_Font.GetFace()->SelectCharMap(fxge::FontEncoding::kUnicode)) {
     pdfium::span<const uint16_t> unicodes =
         UnicodesForPredefinedCharSet(base_encoding);
     for (uint32_t charcode = 0; charcode < 256; charcode++) {
diff --git a/core/fpdfapi/font/cpdf_type1font.cpp b/core/fpdfapi/font/cpdf_type1font.cpp
index 5e33da4..63ca6da 100644
--- a/core/fpdfapi/font/cpdf_type1font.cpp
+++ b/core/fpdfapi/font/cpdf_type1font.cpp
@@ -166,8 +166,7 @@
         return;
       }
     }
-    FXFT_Select_Charmap(m_Font.GetFaceRec(),
-                        static_cast<FT_Encoding>(fxge::FontEncoding::kUnicode));
+    m_Font.GetFace()->SelectCharMap(fxge::FontEncoding::kUnicode);
     if (m_BaseEncoding == FontEncoding::kBuiltin)
       m_BaseEncoding = FontEncoding::kStandard;
 
@@ -227,9 +226,7 @@
     }
 
     bool bUnicode =
-        FXFT_Select_Charmap(
-            m_Font.GetFaceRec(),
-            static_cast<FT_Encoding>(fxge::FontEncoding::kUnicode)) == 0;
+        m_Font.GetFace()->SelectCharMap(fxge::FontEncoding::kUnicode);
     for (uint32_t charcode = 0; charcode < kInternalTableSize; charcode++) {
       const char* name =
           GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode);
@@ -289,10 +286,7 @@
     return;
   }
 
-  bool bUnicode =
-      FXFT_Select_Charmap(
-          m_Font.GetFaceRec(),
-          static_cast<FT_Encoding>(fxge::FontEncoding::kUnicode)) == 0;
+  bool bUnicode = m_Font.GetFace()->SelectCharMap(fxge::FontEncoding::kUnicode);
   for (size_t charcode = 0; charcode < kInternalTableSize; charcode++) {
     const char* name = GetAdobeCharName(m_BaseEncoding, m_CharNames,
                                         static_cast<uint32_t>(charcode));
diff --git a/core/fxge/android/cfpf_skiafont.cpp b/core/fxge/android/cfpf_skiafont.cpp
index ab6ca81..4ee8506 100644
--- a/core/fxge/android/cfpf_skiafont.cpp
+++ b/core/fxge/android/cfpf_skiafont.cpp
@@ -46,8 +46,7 @@
 int32_t CFPF_SkiaFont::GetGlyphIndex(wchar_t wUnicode) {
   if (!m_Face)
     return wUnicode;
-  if (FXFT_Select_Charmap(GetFaceRec(), static_cast<FT_Encoding>(
-                                            fxge::FontEncoding::kUnicode))) {
+  if (!m_Face->SelectCharMap(fxge::FontEncoding::kUnicode)) {
     return 0;
   }
   return FT_Get_Char_Index(GetFaceRec(), wUnicode);
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp
index 71a6ead..44df5a2 100644
--- a/core/fxge/cfx_face.cpp
+++ b/core/fxge/cfx_face.cpp
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "core/fxge/fx_fontencoding.h"
 #include "third_party/base/check.h"
 #include "third_party/base/numerics/safe_conversions.h"
 
@@ -107,6 +108,12 @@
   return {GetRec()->stream->base, GetRec()->stream->size};
 }
 
+bool CFX_Face::SelectCharMap(fxge::FontEncoding encoding) {
+  FT_Error error =
+      FT_Select_Charmap(GetRec(), static_cast<FT_Encoding>(encoding));
+  return !error;
+}
+
 CFX_Face::CFX_Face(FXFT_FaceRec* rec, RetainPtr<Retainable> pDesc)
     : m_pRec(rec), m_pDesc(std::move(pDesc)) {
   DCHECK(m_pRec);
diff --git a/core/fxge/cfx_face.h b/core/fxge/cfx_face.h
index 8040c69..d8f96c0 100644
--- a/core/fxge/cfx_face.h
+++ b/core/fxge/cfx_face.h
@@ -15,6 +15,10 @@
 #include "core/fxge/freetype/fx_freetype.h"
 #include "third_party/base/containers/span.h"
 
+namespace fxge {
+enum class FontEncoding : uint32_t;
+}
+
 class CFX_Face final : public Retainable, public Observable {
  public:
   static RetainPtr<CFX_Face> New(FT_Library library,
@@ -52,6 +56,8 @@
 
   pdfium::span<uint8_t> GetData() const;
 
+  bool SelectCharMap(fxge::FontEncoding encoding);
+
   FXFT_FaceRec* GetRec() { return m_pRec.get(); }
   const FXFT_FaceRec* GetRec() const { return m_pRec.get(); }
 
diff --git a/core/fxge/cfx_unicodeencoding.cpp b/core/fxge/cfx_unicodeencoding.cpp
index 309ba4a..de37a2a 100644
--- a/core/fxge/cfx_unicodeencoding.cpp
+++ b/core/fxge/cfx_unicodeencoding.cpp
@@ -23,21 +23,18 @@
   if (!face)
     return charcode;
 
-  if (FT_Select_Charmap(
-          face, static_cast<FT_Encoding>(fxge::FontEncoding::kUnicode)) == 0) {
+  if (m_pFont->GetFace()->SelectCharMap(fxge::FontEncoding::kUnicode)) {
     return FT_Get_Char_Index(face, charcode);
   }
 
   if (m_pFont->GetSubstFont() &&
       m_pFont->GetSubstFont()->m_Charset == FX_Charset::kSymbol) {
     uint32_t index = 0;
-    if (FT_Select_Charmap(
-            face, static_cast<FT_Encoding>(fxge::FontEncoding::kSymbol)) == 0) {
+    if (m_pFont->GetFace()->SelectCharMap(fxge::FontEncoding::kSymbol)) {
       index = FT_Get_Char_Index(face, charcode);
     }
     if (!index &&
-        !FT_Select_Charmap(
-            face, static_cast<FT_Encoding>(fxge::FontEncoding::kAppleRoman))) {
+        m_pFont->GetFace()->SelectCharMap(fxge::FontEncoding::kAppleRoman)) {
       return FT_Get_Char_Index(face, charcode);
     }
   }
diff --git a/core/fxge/cfx_unicodeencodingex.cpp b/core/fxge/cfx_unicodeencodingex.cpp
index c757599..379ae2c 100644
--- a/core/fxge/cfx_unicodeencodingex.cpp
+++ b/core/fxge/cfx_unicodeencodingex.cpp
@@ -28,8 +28,7 @@
 std::unique_ptr<CFX_UnicodeEncodingEx> FXFM_CreateFontEncoding(
     CFX_Font* pFont,
     fxge::FontEncoding encoding_id) {
-  if (FXFT_Select_Charmap(pFont->GetFaceRec(),
-                          static_cast<FT_Encoding>(encoding_id))) {
+  if (!pFont->GetFace()->SelectCharMap(encoding_id)) {
     return nullptr;
   }
   return std::make_unique<CFX_UnicodeEncodingEx>(pFont, encoding_id);
@@ -55,17 +54,16 @@
     if (encoding_id_ == encoding_id) {
       continue;
     }
-    int error =
-        FXFT_Select_Charmap(face, static_cast<FT_Encoding>(encoding_id));
-    if (error)
+    if (!m_pFont->GetFace()->SelectCharMap(encoding_id)) {
       continue;
+    }
     nIndex = FT_Get_Char_Index(face, charcode);
     if (nIndex > 0) {
       encoding_id_ = encoding_id;
       return nIndex;
     }
   }
-  FXFT_Select_Charmap(face, static_cast<FT_Encoding>(encoding_id_));
+  m_pFont->GetFace()->SelectCharMap(encoding_id_);
   return 0;
 }
 
diff --git a/core/fxge/freetype/fx_freetype.h b/core/fxge/freetype/fx_freetype.h
index f796eb3..afd6604 100644
--- a/core/fxge/freetype/fx_freetype.h
+++ b/core/fxge/freetype/fx_freetype.h
@@ -53,8 +53,6 @@
   std::unique_ptr<FT_MM_Var, FXFTMMVarDeleter> const variation_desc_;
 };
 
-#define FXFT_Select_Charmap(face, encoding) \
-  FT_Select_Charmap(face, static_cast<FT_Encoding>(encoding))
 #define FXFT_Render_Glyph(face, mode) \
   FT_Render_Glyph((face)->glyph, static_cast<enum FT_Render_Mode_>(mode))
 
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp
index ebaf4de..c8d3dd2 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -43,8 +43,7 @@
 
   FXFT_FaceRec* pFaceRec = pFace->GetRec();
   FT_CharMap charmap = pFaceRec->charmap;
-  if (FXFT_Select_Charmap(pFaceRec, static_cast<FT_Encoding>(
-                                        fxge::FontEncoding::kUnicode)) != 0) {
+  if (!pFace->SelectCharMap(fxge::FontEncoding::kUnicode)) {
     return false;
   }
 
@@ -551,13 +550,13 @@
   if (!pFace)
     return false;
 
-  FT_Error retCharmap = FXFT_Select_Charmap(
-      pFace->GetRec(), static_cast<FT_Encoding>(fxge::FontEncoding::kUnicode));
-  FT_Error retIndex = FT_Get_Char_Index(pFace->GetRec(), wcUnicode);
+  bool select_charmap_result =
+      pFace->SelectCharMap(fxge::FontEncoding::kUnicode);
+  FT_Error ret_index = FT_Get_Char_Index(pFace->GetRec(), wcUnicode);
 
   pFace->ClearExternalStream();
 
-  return !retCharmap && retIndex;
+  return select_charmap_result && ret_index;
 }
 
 bool IsPartName(const WideString& name1, const WideString& name2) {