Include more font details in CFX_Font.

CPDF_Font knows more high level details about fonts in PDFs that
CFX_Font does not. Meanwhile, RenderDeviceDriverIface::DrawDeviceText()
takes a CFX_Font*. For DrawDeviceText() implementations to make better
output decisions based on the font type, add more getters/setters to
CFX_Font to plumb through the following data:

- Font type
- Font object's object and generation number as an opaque tag

Bug: chromium:1232526
Change-Id: I65fdd3b240139dfa725a9c5a61afbf7b58e74771
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/84871
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index e4f5955..fbcfc2d 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -492,6 +492,11 @@
       m_DefaultW1 = pDefaultArray->GetIntegerAt(1);
     }
   }
+
+  // TODO(thestig): Better identify font types and identify more font types.
+  if (m_FontType == CIDFontType::kTrueType && IsEmbedded())
+    m_Font.SetFontType(CFX_Font::FontType::kCIDTrueType);
+
   return true;
 }
 
diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp
index c22a560..46112e4 100644
--- a/core/fpdfapi/font/cpdf_font.cpp
+++ b/core/fpdfapi/font/cpdf_font.cpp
@@ -45,6 +45,11 @@
     {0xB7, 0xC2, 0xCB, 0xCE},
     {0xD0, 0xC2, 0xCB, 0xCE}};
 
+uint64_t MakeObjectTag(uint32_t id, uint32_t gen) {
+  uint64_t tag = id;
+  return (tag << 32) | gen;
+}
+
 }  // namespace
 
 CPDF_Font::CPDF_Font(CPDF_Document* pDocument, CPDF_Dictionary* pFontDict)
@@ -213,7 +218,8 @@
   if (!m_pFontFile)
     return;
 
-  if (!m_Font.LoadEmbedded(m_pFontFile->GetSpan(), IsVertWriting())) {
+  uint64_t tag = MakeObjectTag(pFontFile->GetObjNum(), pFontFile->GetGenNum());
+  if (!m_Font.LoadEmbedded(m_pFontFile->GetSpan(), IsVertWriting(), tag)) {
     pData->MaybePurgeFontFileStreamAcc(m_pFontFile->GetStream()->AsStream());
     m_pFontFile = nullptr;
   }
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index 4f0e029..8eafb54 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -297,6 +297,7 @@
 bool CFX_Font::LoadFile(RetainPtr<IFX_SeekableReadStream> pFile,
                         int nFaceIndex) {
   m_bEmbedded = false;
+  m_ObjectTag = 0;
 
   auto pStreamRec = std::make_unique<FXFT_StreamRec>();
   pStreamRec->base = nullptr;
@@ -324,6 +325,7 @@
 #if !defined(OS_WIN)
 void CFX_Font::SetFace(RetainPtr<CFX_Face> face) {
   ClearGlyphCache();
+  m_ObjectTag = 0;
   m_Face = face;
 }
 
@@ -351,6 +353,7 @@
                          bool bVertical) {
   m_bEmbedded = false;
   m_bVertical = bVertical;
+  m_ObjectTag = 0;
   m_pSubstFont = std::make_unique<CFX_SubstFont>();
   m_Face = CFX_GEModule::Get()->GetFontMgr()->FindSubstFont(
       face_name, bTrueType, flags, weight, italic_angle, code_page,
@@ -380,9 +383,10 @@
 }
 
 bool CFX_Font::LoadEmbedded(pdfium::span<const uint8_t> src_span,
-                            bool bForceAsVertical) {
-  if (bForceAsVertical)
-    m_bVertical = true;
+                            bool force_vertical,
+                            uint64_t object_tag) {
+  m_bVertical = force_vertical;
+  m_ObjectTag = object_tag;
   m_FontDataAllocation = std::vector<uint8_t, FxAllocAllocator<uint8_t>>(
       src_span.begin(), src_span.end());
   m_Face = CFX_GEModule::Get()->GetFontMgr()->NewFixedFace(
diff --git a/core/fxge/cfx_font.h b/core/fxge/cfx_font.h
index b3f2b16..3627a43 100644
--- a/core/fxge/cfx_font.h
+++ b/core/fxge/cfx_font.h
@@ -40,6 +40,11 @@
     const char* fontname;  // Name of default font to use with that charset.
   };
 
+  enum class FontType {
+    kUnknown,
+    kCIDTrueType,
+  };
+
   // Pointer to the default character set to TT Font name map. The map is an
   // array of CharsetFontMap structs, with its end indicated by a {-1, nullptr}
   // entry.
@@ -72,7 +77,8 @@
                  bool bVertical);
 
   bool LoadEmbedded(pdfium::span<const uint8_t> src_span,
-                    bool bForceAsVertical);
+                    bool force_vertical,
+                    uint64_t object_tag);
   RetainPtr<CFX_Face> GetFace() const { return m_Face; }
   FXFT_FaceRec* GetFaceRec() const {
     return m_Face ? m_Face->GetRec() : nullptr;
@@ -115,6 +121,9 @@
   bool IsEmbedded() const { return m_bEmbedded; }
   uint8_t* GetSubData() const { return m_pGsubData.get(); }
   void SetSubData(uint8_t* data) { m_pGsubData.reset(data); }
+  FontType GetFontType() const { return m_FontType; }
+  void SetFontType(FontType type) { m_FontType = type; }
+  uint64_t GetObjectTag() const { return m_ObjectTag; }
   pdfium::span<uint8_t> GetFontSpan() const { return m_FontData; }
   void AdjustMMParams(int glyph_index, int dest_width, int weight) const;
   std::unique_ptr<CFX_Path> LoadGlyphPathImpl(uint32_t glyph_index,
@@ -150,6 +159,8 @@
   std::unique_ptr<uint8_t, FxFreeDeleter> m_pGsubData;
   std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_FontDataAllocation;
   pdfium::span<uint8_t> m_FontData;
+  FontType m_FontType = FontType::kUnknown;
+  uint64_t m_ObjectTag = 0;
   bool m_bEmbedded = false;
   bool m_bVertical = false;
 #if defined(OS_APPLE)
diff --git a/fpdfsdk/fpdf_edittext.cpp b/fpdfsdk/fpdf_edittext.cpp
index c7fb03c..3fcd0b3 100644
--- a/fpdfsdk/fpdf_edittext.cpp
+++ b/fpdfsdk/fpdf_edittext.cpp
@@ -520,7 +520,7 @@
   // TODO(npm): Maybe use FT_Get_X11_Font_Format to check format? Otherwise, we
   // are allowing giving any font that can be loaded on freetype and setting it
   // as any font type.
-  if (!pFont->LoadEmbedded(span, false))
+  if (!pFont->LoadEmbedded(span, /*force_vertical=*/false, /*object_tag=*/0))
     return nullptr;
 
   // Caller takes ownership.