Remove circular includes from fpdfapi/font to fpdfapi/page.

Introduce an abstract factory interface which the font layer
can call to create forms as needed. Move the abstract interface
declarations up to the top-level cpdf_form.h file so that
callers can see them.

Change-Id: Iffd404766da896fd9e9578910073f0eb688c7dca
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/58030
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp
index 5fbffd5..4e2e7bd 100644
--- a/core/fpdfapi/font/cpdf_font.cpp
+++ b/core/fpdfapi/font/cpdf_font.cpp
@@ -302,12 +302,14 @@
   pDict->SetNewFor<CPDF_Name>("BaseFont", fontname);
   pDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding");
   return pFontGlobals->Set(pDoc, font_id.value(),
-                           CPDF_Font::Create(nullptr, pDict.Get()));
+                           CPDF_Font::Create(nullptr, pDict.Get(), nullptr));
 }
 
 // static
-std::unique_ptr<CPDF_Font> CPDF_Font::Create(CPDF_Document* pDoc,
-                                             CPDF_Dictionary* pFontDict) {
+std::unique_ptr<CPDF_Font> CPDF_Font::Create(
+    CPDF_Document* pDoc,
+    CPDF_Dictionary* pFontDict,
+    std::unique_ptr<FormFactoryIface> pFactory) {
   ByteString type = pFontDict->GetStringFor("Subtype");
   std::unique_ptr<CPDF_Font> pFont;
   if (type == "TrueType") {
@@ -324,7 +326,8 @@
     if (!pFont)
       pFont = pdfium::MakeUnique<CPDF_TrueTypeFont>(pDoc, pFontDict);
   } else if (type == "Type3") {
-    pFont = pdfium::MakeUnique<CPDF_Type3Font>(pDoc, pFontDict);
+    pFont = pdfium::MakeUnique<CPDF_Type3Font>(pDoc, pFontDict,
+                                               std::move(pFactory));
   } else if (type == "Type0") {
     pFont = pdfium::MakeUnique<CPDF_CIDFont>(pDoc, pFontDict);
   } else {
diff --git a/core/fpdfapi/font/cpdf_font.h b/core/fpdfapi/font/cpdf_font.h
index 34141e0..ecaedcf 100644
--- a/core/fpdfapi/font/cpdf_font.h
+++ b/core/fpdfapi/font/cpdf_font.h
@@ -8,6 +8,7 @@
 #define CORE_FPDFAPI_FONT_CPDF_FONT_H_
 
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "build/build_config.h"
@@ -18,19 +19,48 @@
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/cfx_font.h"
 
+class CFX_DIBitmap;
 class CFX_SubstFont;
 class CPDF_CIDFont;
 class CPDF_Document;
 class CPDF_Object;
 class CPDF_TrueTypeFont;
 class CPDF_Type1Font;
+class CPDF_Type3Char;
 class CPDF_Type3Font;
 class CPDF_ToUnicodeMap;
 
 class CPDF_Font {
  public:
-  static std::unique_ptr<CPDF_Font> Create(CPDF_Document* pDoc,
-                                           CPDF_Dictionary* pFontDict);
+  // Callback mechanism for Type3 fonts to get pixels from forms.
+  class FormIface {
+   public:
+    virtual ~FormIface() {}
+
+    virtual void ParseContentForType3Char(CPDF_Type3Char* pChar) = 0;
+    virtual bool HasPageObjects() const = 0;
+    virtual CFX_FloatRect CalcBoundingBox() const = 0;
+    virtual Optional<std::pair<RetainPtr<CFX_DIBitmap>, CFX_Matrix>>
+    GetBitmapAndMatrixFromSoleImageOfForm() const = 0;
+  };
+
+  // Callback mechanism for Type3 fonts to get new forms from upper layers.
+  class FormFactoryIface {
+   public:
+    virtual ~FormFactoryIface() {}
+
+    virtual std::unique_ptr<FormIface> CreateForm(
+        CPDF_Document* pDocument,
+        CPDF_Dictionary* pPageResources,
+        CPDF_Stream* pFormStream) = 0;
+  };
+
+  // |pFactory| only required for Type3 fonts.
+  static std::unique_ptr<CPDF_Font> Create(
+      CPDF_Document* pDoc,
+      CPDF_Dictionary* pFontDict,
+      std::unique_ptr<FormFactoryIface> pFactory);
+
   static CPDF_Font* GetStockFont(CPDF_Document* pDoc, ByteStringView fontname);
   static const uint32_t kInvalidCharCode = static_cast<uint32_t>(-1);
 
diff --git a/core/fpdfapi/font/cpdf_type3char.cpp b/core/fpdfapi/font/cpdf_type3char.cpp
index e8d8bf5..1bf5ebb 100644
--- a/core/fpdfapi/font/cpdf_type3char.cpp
+++ b/core/fpdfapi/font/cpdf_type3char.cpp
@@ -58,7 +58,8 @@
   m_BBox.top = FXSYS_round(TextUnitToGlyphUnit(pData[5]));
 }
 
-void CPDF_Type3Char::Transform(FormIface* pForm, const CFX_Matrix& matrix) {
+void CPDF_Type3Char::Transform(CPDF_Font::FormIface* pForm,
+                               const CFX_Matrix& matrix) {
   m_Width = m_Width * matrix.GetXUnit() + 0.5f;
 
   CFX_FloatRect char_rect;
@@ -72,7 +73,7 @@
   m_BBox = matrix.TransformRect(char_rect).ToRoundedFxRect();
 }
 
-void CPDF_Type3Char::SetForm(std::unique_ptr<FormIface> pForm) {
+void CPDF_Type3Char::SetForm(std::unique_ptr<CPDF_Font::FormIface> pForm) {
   m_pForm = std::move(pForm);
 }
 
diff --git a/core/fpdfapi/font/cpdf_type3char.h b/core/fpdfapi/font/cpdf_type3char.h
index acf6190..05ade5f 100644
--- a/core/fpdfapi/font/cpdf_type3char.h
+++ b/core/fpdfapi/font/cpdf_type3char.h
@@ -10,6 +10,7 @@
 #include <memory>
 #include <utility>
 
+#include "core/fpdfapi/font/cpdf_font.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/retain_ptr.h"
@@ -19,17 +20,6 @@
 
 class CPDF_Type3Char {
  public:
-  class FormIface {
-   public:
-    virtual ~FormIface() {}
-
-    virtual void ParseContentForType3Char(CPDF_Type3Char* pChar) = 0;
-    virtual bool HasPageObjects() const = 0;
-    virtual CFX_FloatRect CalcBoundingBox() const = 0;
-    virtual Optional<std::pair<RetainPtr<CFX_DIBitmap>, CFX_Matrix>>
-    GetBitmapAndMatrixFromSoleImageOfForm() const = 0;
-  };
-
   CPDF_Type3Char();
   ~CPDF_Type3Char();
 
@@ -38,7 +28,7 @@
 
   bool LoadBitmapFromSoleImageOfForm();
   void InitializeFromStreamData(bool bColored, const float* pData);
-  void Transform(FormIface* pForm, const CFX_Matrix& matrix);
+  void Transform(CPDF_Font::FormIface* pForm, const CFX_Matrix& matrix);
 
   RetainPtr<CFX_DIBitmap> GetBitmap();
   const RetainPtr<CFX_DIBitmap>& GetBitmap() const;
@@ -48,11 +38,11 @@
   const CFX_Matrix& matrix() const { return m_ImageMatrix; }
   const FX_RECT& bbox() const { return m_BBox; }
 
-  const FormIface* form() const { return m_pForm.get(); }
-  void SetForm(std::unique_ptr<FormIface> pForm);
+  const CPDF_Font::FormIface* form() const { return m_pForm.get(); }
+  void SetForm(std::unique_ptr<CPDF_Font::FormIface> pForm);
 
  private:
-  std::unique_ptr<FormIface> m_pForm;
+  std::unique_ptr<CPDF_Font::FormIface> m_pForm;
   RetainPtr<CFX_DIBitmap> m_pBitmap;
   bool m_bColored = false;
   uint32_t m_Width = 0;
diff --git a/core/fpdfapi/font/cpdf_type3font.cpp b/core/fpdfapi/font/cpdf_type3font.cpp
index f7c58c2..e559a5b 100644
--- a/core/fpdfapi/font/cpdf_type3font.cpp
+++ b/core/fpdfapi/font/cpdf_type3font.cpp
@@ -10,7 +10,6 @@
 #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"
@@ -25,8 +24,10 @@
 }  // namespace
 
 CPDF_Type3Font::CPDF_Type3Font(CPDF_Document* pDocument,
-                               CPDF_Dictionary* pFontDict)
-    : CPDF_SimpleFont(pDocument, pFontDict) {
+                               CPDF_Dictionary* pFontDict,
+                               std::unique_ptr<FormFactoryIface> pFormFactory)
+    : CPDF_SimpleFont(pDocument, pFontDict),
+      m_pFormFactory(std::move(pFormFactory)) {
   ASSERT(GetDocument());
   memset(m_CharWidthL, 0, sizeof(m_CharWidthL));
 }
@@ -110,11 +111,10 @@
   if (!pStream)
     return nullptr;
 
-  std::unique_ptr<CPDF_Type3Char::FormIface> pForm =
-      pdfium::MakeUnique<CPDF_Form>(
-          m_pDocument.Get(),
-          m_pFontResources ? m_pFontResources.Get() : m_pPageResources.Get(),
-          pStream);
+  std::unique_ptr<CPDF_Font::FormIface> pForm = m_pFormFactory->CreateForm(
+      m_pDocument.Get(),
+      m_pFontResources ? m_pFontResources.Get() : m_pPageResources.Get(),
+      pStream);
 
   auto pNewChar = pdfium::MakeUnique<CPDF_Type3Char>();
 
diff --git a/core/fpdfapi/font/cpdf_type3font.h b/core/fpdfapi/font/cpdf_type3font.h
index 080b216..fde66d0 100644
--- a/core/fpdfapi/font/cpdf_type3font.h
+++ b/core/fpdfapi/font/cpdf_type3font.h
@@ -15,11 +15,15 @@
 #include "core/fxcrt/fx_system.h"
 
 class CPDF_Dictionary;
+class CPDF_Document;
+class CPDF_Stream;
 class CPDF_Type3Char;
 
 class CPDF_Type3Font final : public CPDF_SimpleFont {
  public:
-  CPDF_Type3Font(CPDF_Document* pDocument, CPDF_Dictionary* pFontDict);
+  CPDF_Type3Font(CPDF_Document* pDocument,
+                 CPDF_Dictionary* pFontDict,
+                 std::unique_ptr<FormFactoryIface> pFormFactory);
   ~CPDF_Type3Font() override;
 
   // CPDF_Font:
@@ -44,14 +48,15 @@
   // CPDF_SimpleFont:
   void LoadGlyphMap() override;
 
+  // The depth char loading is in, to avoid recurive calling LoadChar().
+  int m_CharLoadingDepth = 0;
   CFX_Matrix m_FontMatrix;
-  uint32_t m_CharWidthL[256];
+  std::unique_ptr<FormFactoryIface> m_pFormFactory;
   RetainPtr<CPDF_Dictionary> m_pCharProcs;
   RetainPtr<CPDF_Dictionary> m_pPageResources;
   RetainPtr<CPDF_Dictionary> m_pFontResources;
   std::map<uint32_t, std::unique_ptr<CPDF_Type3Char>> m_CacheMap;
-  // The depth char loading is in, to avoid recurive calling LoadChar().
-  int m_CharLoadingDepth = 0;
+  uint32_t m_CharWidthL[256];
 };
 
 #endif  // CORE_FPDFAPI_FONT_CPDF_TYPE3FONT_H_
diff --git a/core/fpdfapi/page/BUILD.gn b/core/fpdfapi/page/BUILD.gn
index 6244b8d..8ac278e 100644
--- a/core/fpdfapi/page/BUILD.gn
+++ b/core/fpdfapi/page/BUILD.gn
@@ -106,7 +106,7 @@
     "../font",
     "../parser",
   ]
-  allow_circular_includes_from = [ "../font" ]
+  allow_circular_includes_from = []
   if (pdf_use_skia || pdf_use_skia_paths) {
     allow_circular_includes_from += [ "../../fxge" ]
   }
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index bfd40bb..55aacf8 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -15,6 +15,7 @@
 #include "build/build_config.h"
 #include "core/fdrm/fx_crypt.h"
 #include "core/fpdfapi/font/cpdf_type1font.h"
+#include "core/fpdfapi/page/cpdf_form.h"
 #include "core/fpdfapi/page/cpdf_iccprofile.h"
 #include "core/fpdfapi/page/cpdf_image.h"
 #include "core/fpdfapi/page/cpdf_pagemodule.h"
@@ -154,6 +155,16 @@
   return pFontDesc;
 }
 
+class FormFactory : public CPDF_Font::FormFactoryIface {
+  std::unique_ptr<CPDF_Font::FormIface> CreateForm(
+      CPDF_Document* pDocument,
+      CPDF_Dictionary* pPageResources,
+      CPDF_Stream* pFormStream) override {
+    return pdfium::MakeUnique<CPDF_Form>(pDocument, pPageResources,
+                                         pFormStream);
+  }
+};
+
 }  // namespace
 
 // static
@@ -230,8 +241,8 @@
       return pFontData->AddRef();
     }
   }
-  std::unique_ptr<CPDF_Font> pFont =
-      CPDF_Font::Create(GetDocument(), pFontDict);
+  std::unique_ptr<CPDF_Font> pFont = CPDF_Font::Create(
+      GetDocument(), pFontDict, pdfium::MakeUnique<FormFactory>());
   if (!pFont)
     return nullptr;
 
@@ -280,7 +291,9 @@
                   pEncoding->Realize(GetDocument()->GetByteStringPool()));
   }
 
-  std::unique_ptr<CPDF_Font> pFont = CPDF_Font::Create(GetDocument(), pDict);
+  // Note: NULL FormFactoryIface OK since known Type1 font from above.
+  std::unique_ptr<CPDF_Font> pFont =
+      CPDF_Font::Create(GetDocument(), pDict, nullptr);
   if (!pFont)
     return nullptr;
 
diff --git a/core/fpdfapi/page/cpdf_form.cpp b/core/fpdfapi/page/cpdf_form.cpp
index 5b3bf73..0bc59a3 100644
--- a/core/fpdfapi/page/cpdf_form.cpp
+++ b/core/fpdfapi/page/cpdf_form.cpp
@@ -84,6 +84,10 @@
   ContinueParse(nullptr);
 }
 
+bool CPDF_Form::HasPageObjects() const {
+  return GetPageObjectCount() != 0;
+}
+
 CFX_FloatRect CPDF_Form::CalcBoundingBox() const {
   if (GetPageObjectCount() == 0)
     return CFX_FloatRect();
@@ -106,10 +110,6 @@
   return m_pFormStream.Get();
 }
 
-bool CPDF_Form::HasPageObjects() const {
-  return GetPageObjectCount() != 0;
-}
-
 Optional<std::pair<RetainPtr<CFX_DIBitmap>, CFX_Matrix>>
 CPDF_Form::GetBitmapAndMatrixFromSoleImageOfForm() const {
   if (GetPageObjectCount() != 1)
diff --git a/core/fpdfapi/page/cpdf_form.h b/core/fpdfapi/page/cpdf_form.h
index 5c104b2..e8b9d1f 100644
--- a/core/fpdfapi/page/cpdf_form.h
+++ b/core/fpdfapi/page/cpdf_form.h
@@ -11,7 +11,7 @@
 #include <set>
 #include <utility>
 
-#include "core/fpdfapi/font/cpdf_type3char.h"
+#include "core/fpdfapi/font/cpdf_font.h"
 #include "core/fpdfapi/page/cpdf_pageobjectholder.h"
 
 class CFX_Matrix;
@@ -23,7 +23,7 @@
 class CPDF_Type3Char;
 
 class CPDF_Form final : public CPDF_PageObjectHolder,
-                        public CPDF_Type3Char::FormIface {
+                        public CPDF_Font::FormIface {
  public:
   // Helper method to choose the first non-null resources dictionary.
   static CPDF_Dictionary* ChooseResourcesDict(CPDF_Dictionary* pResources,
@@ -39,7 +39,7 @@
             CPDF_Dictionary* pParentResources);
   ~CPDF_Form() override;
 
-  // CPDF_Type3Char::FormIface:
+  // CPDF_Font::FormIface:
   void ParseContentForType3Char(CPDF_Type3Char* pType3Char) override;
   bool HasPageObjects() const override;
   CFX_FloatRect CalcBoundingBox() const override;