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();