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;