Encapsulate CTTFontDesc.

Change-Id: I602890527dae9e2e2de16e70bccfa1793e31e0f8
Reviewed-on: https://pdfium-review.googlesource.com/22530
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
diff --git a/core/fxge/cfx_fontmgr.cpp b/core/fxge/cfx_fontmgr.cpp
index 2990204..e2be93e 100644
--- a/core/fxge/cfx_fontmgr.cpp
+++ b/core/fxge/cfx_fontmgr.cpp
@@ -124,9 +124,9 @@
     return nullptr;
 
   CTTFontDesc* pFontDesc = it->second.get();
-  *pFontData = pFontDesc->m_pFontData;
-  pFontDesc->m_RefCount++;
-  return pFontDesc->m_SingleFace;
+  *pFontData = pFontDesc->FontData();
+  pFontDesc->AddRef();
+  return pFontDesc->SingleFace();
 }
 
 FXFT_Face CFX_FontMgr::AddCachedFace(const ByteString& face_name,
@@ -135,26 +135,21 @@
                                      uint8_t* pData,
                                      uint32_t size,
                                      int face_index) {
-  auto pFontDesc = pdfium::MakeUnique<CTTFontDesc>();
-  pFontDesc->m_Type = 1;
-  pFontDesc->m_SingleFace = nullptr;
-  pFontDesc->m_pFontData = pData;
-  pFontDesc->m_RefCount = 1;
-
   InitFTLibrary();
-  FXFT_Library library = m_FTLibrary;
-  int ret = FXFT_New_Memory_Face(library, pData, size, face_index,
-                                 &pFontDesc->m_SingleFace);
+
+  FXFT_Face face = nullptr;
+  int ret = FXFT_New_Memory_Face(m_FTLibrary, pData, size, face_index, &face);
   if (ret)
     return nullptr;
 
-  ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace, 64, 64);
+  ret = FXFT_Set_Pixel_Sizes(face, 64, 64);
   if (ret)
     return nullptr;
 
+  auto pFontDesc = pdfium::MakeUnique<CTTFontDesc>(pData, face);
   CTTFontDesc* pResult = pFontDesc.get();
   m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = std::move(pFontDesc);
-  return pResult->m_SingleFace;
+  return pResult->SingleFace();
 }
 
 FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size,
@@ -166,14 +161,14 @@
     return nullptr;
 
   CTTFontDesc* pFontDesc = it->second.get();
-  *pFontData = pFontDesc->m_pFontData;
-  pFontDesc->m_RefCount++;
-  int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
-  if (!pFontDesc->m_TTCFaces[face_index]) {
-    pFontDesc->m_TTCFaces[face_index] =
-        GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
+  *pFontData = pFontDesc->FontData();
+  int face_index = GetTTCIndex(pFontDesc->FontData(), ttc_size, font_offset);
+  if (!pFontDesc->TTCFace(face_index)) {
+    pFontDesc->SetTTCFace(
+        face_index, GetFixedFace(pFontDesc->FontData(), ttc_size, face_index));
   }
-  return pFontDesc->m_TTCFaces[face_index];
+  pFontDesc->AddRef();
+  return pFontDesc->TTCFace(face_index);
 }
 
 FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size,
@@ -181,18 +176,11 @@
                                         uint8_t* pData,
                                         uint32_t size,
                                         int font_offset) {
-  auto pFontDesc = pdfium::MakeUnique<CTTFontDesc>();
-  pFontDesc->m_Type = 2;
-  pFontDesc->m_pFontData = pData;
-  for (int i = 0; i < 16; i++)
-    pFontDesc->m_TTCFaces[i] = nullptr;
-  pFontDesc->m_RefCount++;
-  CTTFontDesc* pResult = pFontDesc.get();
+  int face_index = GetTTCIndex(pData, ttc_size, font_offset);
+  FXFT_Face face = GetFixedFace(pData, ttc_size, face_index);
+  auto pFontDesc = pdfium::MakeUnique<CTTFontDesc>(pData, face_index, face);
   m_FaceMap[KeyNameFromSize(ttc_size, checksum)] = std::move(pFontDesc);
-  int face_index = GetTTCIndex(pResult->m_pFontData, ttc_size, font_offset);
-  pResult->m_TTCFaces[face_index] =
-      GetFixedFace(pResult->m_pFontData, ttc_size, face_index);
-  return pResult->m_TTCFaces[face_index];
+  return face;
 }
 
 FXFT_Face CFX_FontMgr::GetFixedFace(const uint8_t* pData,
@@ -218,11 +206,11 @@
     return;
   bool bNeedFaceDone = true;
   for (auto it = m_FaceMap.begin(); it != m_FaceMap.end(); ++it) {
-    int nRet = it->second->ReleaseFace(face);
-    if (nRet == -1)
+    CTTFontDesc::ReleaseStatus nRet = it->second->ReleaseFace(face);
+    if (nRet == CTTFontDesc::kNotAppropriate)
       continue;
     bNeedFaceDone = false;
-    if (nRet == 0)
+    if (nRet == CTTFontDesc::kReleased)
       m_FaceMap.erase(it);
     break;
   }
diff --git a/core/fxge/cttfontdesc.cpp b/core/fxge/cttfontdesc.cpp
index cf900a8..bdf2451 100644
--- a/core/fxge/cttfontdesc.cpp
+++ b/core/fxge/cttfontdesc.cpp
@@ -7,32 +7,62 @@
 #include "core/fxge/cttfontdesc.h"
 
 #include "core/fxge/fx_freetype.h"
+#include "third_party/base/stl_util.h"
+
+CTTFontDesc::CTTFontDesc(uint8_t* pData, FXFT_Face face)
+    : m_bIsTTC(false), m_SingleFace(face), m_pFontData(pData) {}
+
+CTTFontDesc::CTTFontDesc(uint8_t* pData, size_t index, FXFT_Face face)
+    : m_bIsTTC(true), m_pFontData(pData) {
+  for (size_t i = 0; i < FX_ArraySize(m_TTCFaces); i++)
+    m_TTCFaces[i] = nullptr;
+  SetTTCFace(index, face);
+}
 
 CTTFontDesc::~CTTFontDesc() {
-  if (m_Type == 1) {
-    if (m_SingleFace)
-      FXFT_Done_Face(m_SingleFace);
-  } else if (m_Type == 2) {
-    for (int i = 0; i < 16; i++) {
+  ASSERT(m_RefCount == 0);
+  if (m_bIsTTC) {
+    for (size_t i = 0; i < FX_ArraySize(m_TTCFaces); i++) {
       if (m_TTCFaces[i])
         FXFT_Done_Face(m_TTCFaces[i]);
     }
+  } else {
+    if (m_SingleFace)
+      FXFT_Done_Face(m_SingleFace);
   }
   FX_Free(m_pFontData);
 }
 
-int CTTFontDesc::ReleaseFace(FXFT_Face face) {
-  if (m_Type == 1) {
+void CTTFontDesc::SetTTCFace(size_t index, FXFT_Face face) {
+  ASSERT(m_bIsTTC);
+  ASSERT(index < FX_ArraySize(m_TTCFaces));
+  m_TTCFaces[index] = face;
+}
+
+void CTTFontDesc::AddRef() {
+  ASSERT(m_RefCount > 0);
+  ++m_RefCount;
+}
+
+CTTFontDesc::ReleaseStatus CTTFontDesc::ReleaseFace(FXFT_Face face) {
+  if (m_bIsTTC) {
+    if (!pdfium::ContainsValue(m_TTCFaces, face))
+      return kNotAppropriate;
+  } else {
     if (m_SingleFace != face)
-      return -1;
-  } else if (m_Type == 2) {
-    int i;
-    for (i = 0; i < 16; i++) {
-      if (m_TTCFaces[i] == face)
-        break;
-    }
-    if (i == 16)
-      return -1;
+      return kNotAppropriate;
   }
-  return --m_RefCount;
+  ASSERT(m_RefCount > 0);
+  return --m_RefCount == 0 ? kReleased : kNotReleased;
+}
+
+FXFT_Face CTTFontDesc::SingleFace() const {
+  ASSERT(!m_bIsTTC);
+  return m_SingleFace;
+}
+
+FXFT_Face CTTFontDesc::TTCFace(size_t index) const {
+  ASSERT(m_bIsTTC);
+  ASSERT(index < FX_ArraySize(m_TTCFaces));
+  return m_TTCFaces[index];
 }
diff --git a/core/fxge/cttfontdesc.h b/core/fxge/cttfontdesc.h
index ee1e0b0..b48e78c 100644
--- a/core/fxge/cttfontdesc.h
+++ b/core/fxge/cttfontdesc.h
@@ -12,21 +12,41 @@
 
 class CTTFontDesc {
  public:
-  CTTFontDesc() : m_Type(0), m_pFontData(nullptr), m_RefCount(0) {}
-  ~CTTFontDesc();
-  // ret < 0, releaseface not appropriate for this object.
-  // ret == 0, object released
-  // ret > 0, object still alive, other referrers.
-  int ReleaseFace(FXFT_Face face);
+  enum ReleaseStatus {
+    kNotAppropriate,  // ReleaseFace() not appropriate for given object.
+    kReleased,
+    kNotReleased  // Object still alive.
+  };
 
-  int m_Type;
+  // Single face ctor.
+  CTTFontDesc(uint8_t* pData, FXFT_Face face);
+
+  // TTC face ctor.
+  CTTFontDesc(uint8_t* pData, size_t index, FXFT_Face face);
+
+  ~CTTFontDesc();
+
+  void SetTTCFace(size_t index, FXFT_Face face);
+
+  void AddRef();
+
+  // May not decrement refcount, depending on the value of |face|.
+  ReleaseStatus ReleaseFace(FXFT_Face face);
+
+  uint8_t* FontData() const { return m_pFontData; }
+
+  FXFT_Face SingleFace() const;
+  FXFT_Face TTCFace(size_t index) const;
+
+ private:
+  const bool m_bIsTTC;
 
   union {
-    FXFT_Face m_SingleFace;
+    const FXFT_Face m_SingleFace;
     FXFT_Face m_TTCFaces[16];
   };
-  uint8_t* m_pFontData;
-  int m_RefCount;
+  uint8_t* const m_pFontData;
+  int m_RefCount = 1;
 };
 
 #endif  // CORE_FXGE_CTTFONTDESC_H_