Pass form to CPDF_Type3Char constructor.

First step towards getting type3 char's out of form lifetime
management. CPDF_Type3Char provides a ResetForm() method to
its callers, which is a hint that they should be doing the
lifetime management themselves.

Callers can then invoke form parse directly, without the
need for a helper method.

-- Use AutoRestorer to track recursion depth.

Change-Id: Ib0a9b422c35f1b98d77ce2d9b51fd656d7cf045b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/57652
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_type3char.cpp b/core/fpdfapi/font/cpdf_type3char.cpp
index 5e04065..c008d5b 100644
--- a/core/fpdfapi/font/cpdf_type3char.cpp
+++ b/core/fpdfapi/font/cpdf_type3char.cpp
@@ -22,12 +22,8 @@
 
 }  // namespace
 
-CPDF_Type3Char::CPDF_Type3Char(CPDF_Document* pDocument,
-                               CPDF_Dictionary* pPageResources,
-                               CPDF_Stream* pFormStream)
-    : m_pForm(pdfium::MakeUnique<CPDF_Form>(pDocument,
-                                            pPageResources,
-                                            pFormStream)) {}
+CPDF_Type3Char::CPDF_Type3Char(std::unique_ptr<CPDF_Form> pForm)
+    : m_pForm(std::move(pForm)) {}
 
 CPDF_Type3Char::~CPDF_Type3Char() = default;
 
@@ -100,10 +96,6 @@
   m_pForm.reset();
 }
 
-void CPDF_Type3Char::ParseContent() {
-  m_pForm->ParseContent(nullptr, nullptr, this, nullptr);
-}
-
 bool CPDF_Type3Char::HasPageObjects() const {
   return !!m_pForm->GetPageObjectCount();
 }
diff --git a/core/fpdfapi/font/cpdf_type3char.h b/core/fpdfapi/font/cpdf_type3char.h
index 9edd6cd..c52f5e7 100644
--- a/core/fpdfapi/font/cpdf_type3char.h
+++ b/core/fpdfapi/font/cpdf_type3char.h
@@ -14,17 +14,12 @@
 #include "core/fxcrt/retain_ptr.h"
 
 class CFX_DIBitmap;
-class CPDF_Dictionary;
-class CPDF_Document;
 class CPDF_Form;
 class CPDF_RenderContext;
-class CPDF_Stream;
 
 class CPDF_Type3Char {
  public:
-  CPDF_Type3Char(CPDF_Document* pDocument,
-                 CPDF_Dictionary* pPageResources,
-                 CPDF_Stream* pFormStream);
+  explicit CPDF_Type3Char(std::unique_ptr<CPDF_Form> pForm);
   ~CPDF_Type3Char();
 
   static float TextUnitToGlyphUnit(float fTextUnit);
@@ -33,8 +28,6 @@
   bool LoadBitmap(CPDF_RenderContext* pContext);
   void InitializeFromStreamData(bool bColored, const float* pData);
   void Transform(const CFX_Matrix& matrix);
-  void ResetForm();
-  void ParseContent();
   bool HasPageObjects() const;
 
   RetainPtr<CFX_DIBitmap> GetBitmap();
@@ -45,12 +38,11 @@
   const CFX_Matrix& matrix() const { return m_ImageMatrix; }
   const FX_RECT& bbox() const { return m_BBox; }
 
- private:
-  friend class CPDF_RenderStatus;
-
   const CPDF_Form* form() const { return m_pForm.get(); }
   CPDF_Form* form() { return m_pForm.get(); }
+  void ResetForm();
 
+ private:
   std::unique_ptr<CPDF_Form> m_pForm;
   RetainPtr<CFX_DIBitmap> m_pBitmap;
   bool m_bColored = false;
diff --git a/core/fpdfapi/font/cpdf_type3font.cpp b/core/fpdfapi/font/cpdf_type3font.cpp
index 85b9ea3..64343ed 100644
--- a/core/fpdfapi/font/cpdf_type3font.cpp
+++ b/core/fpdfapi/font/cpdf_type3font.cpp
@@ -10,9 +10,11 @@
 #include <utility>
 
 #include "core/fpdfapi/font/cpdf_type3char.h"
+#include "core/fpdfapi/page/cpdf_form.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fxcrt/autorestorer.h"
 #include "core/fxcrt/fx_system.h"
 #include "third_party/base/ptr_util.h"
 
@@ -106,17 +108,22 @@
   if (!pStream)
     return nullptr;
 
-  auto pNewChar = pdfium::MakeUnique<CPDF_Type3Char>(
+  auto form = pdfium::MakeUnique<CPDF_Form>(
       m_pDocument.Get(),
       m_pFontResources ? m_pFontResources.Get() : m_pPageResources.Get(),
       pStream);
 
+  CPDF_Form* pForm = form.get();
+  auto pNewChar = pdfium::MakeUnique<CPDF_Type3Char>(std::move(form));
+
   // This can trigger recursion into this method. The content of |m_CacheMap|
   // can change as a result. Thus after it returns, check the cache again for
   // a cache hit.
-  m_CharLoadingDepth++;
-  pNewChar->ParseContent();
-  m_CharLoadingDepth--;
+  {
+    AutoRestorer<int> restorer(&m_CharLoadingDepth);
+    m_CharLoadingDepth++;
+    pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr);
+  }
   it = m_CacheMap.find(charcode);
   if (it != m_CacheMap.end())
     return it->second.get();