From e4f2f4a3f4fd3e9f372912f4151d7c7843f9556f Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Mon, 15 Oct 2018 18:51:11 +0000 Subject: Use more UnownedPtr in CPDF_FormControl. To make this work, remove an UnownedPtr vector in CPDF_FormField and make CPDF_InteractiveForm manage it instead. Also simplify some code within CPDF_FormControl and CPDF_InteractiveForm. Change-Id: Ifc3a979dcdb992376a48db7a40840d2e76078500 Reviewed-on: https://pdfium-review.googlesource.com/c/43938 Commit-Queue: Lei Zhang Reviewed-by: Tom Sepez --- core/fpdfdoc/cpdf_formcontrol.cpp | 22 +++++++++------------- core/fpdfdoc/cpdf_formcontrol.h | 4 ++-- core/fpdfdoc/cpdf_formfield.cpp | 21 ++++++++++++++++----- core/fpdfdoc/cpdf_formfield.h | 12 +++--------- core/fpdfdoc/cpdf_interactiveform.cpp | 19 +++++++++++++------ core/fpdfdoc/cpdf_interactiveform.h | 10 ++++++++-- 6 files changed, 51 insertions(+), 37 deletions(-) diff --git a/core/fpdfdoc/cpdf_formcontrol.cpp b/core/fpdfdoc/cpdf_formcontrol.cpp index a1f1f8f26e..edd5fe566c 100644 --- a/core/fpdfdoc/cpdf_formcontrol.cpp +++ b/core/fpdfdoc/cpdf_formcontrol.cpp @@ -71,10 +71,8 @@ WideString CPDF_FormControl::GetExportValue() const { GetType() == CPDF_FormField::kRadioButton); ByteString csOn = GetOnStateName(); CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pField->GetDict(), "Opt")); - if (pArray) { - int iIndex = m_pField->GetControlIndex(this); - csOn = pArray->GetStringAt(iIndex); - } + if (pArray) + csOn = pArray->GetStringAt(m_pField->GetControlIndex(this)); if (csOn.IsEmpty()) csOn = "Yes"; return PDF_DecodeText(csOn); @@ -196,9 +194,9 @@ CPDF_DefaultAppearance CPDF_FormControl::GetDefaultAppearance() const { return CPDF_DefaultAppearance(m_pWidgetDict->GetStringFor("DA")); CPDF_Object* pObj = FPDF_GetFieldAttr(m_pField->GetDict(), "DA"); - if (pObj) - return CPDF_DefaultAppearance(pObj->GetString()); - return m_pField->GetForm()->GetDefaultAppearance(); + if (!pObj) + return m_pForm->GetDefaultAppearance(); + return CPDF_DefaultAppearance(pObj->GetString()); } CPDF_Font* CPDF_FormControl::GetDefaultControlFont() { @@ -214,14 +212,13 @@ CPDF_Font* CPDF_FormControl::GetDefaultControlFont() { if (pFonts) { CPDF_Dictionary* pElement = pFonts->GetDictFor(*csFontNameTag); if (pElement) { - CPDF_Font* pFont = - m_pField->GetForm()->GetDocument()->LoadFont(pElement); + CPDF_Font* pFont = m_pForm->GetDocument()->LoadFont(pElement); if (pFont) return pFont; } } } - if (CPDF_Font* pFormFont = m_pField->GetForm()->GetFormFont(*csFontNameTag)) + if (CPDF_Font* pFormFont = m_pForm->GetFormFont(*csFontNameTag)) return pFormFont; CPDF_Dictionary* pPageDict = m_pWidgetDict->GetDictFor("P"); @@ -231,8 +228,7 @@ CPDF_Font* CPDF_FormControl::GetDefaultControlFont() { if (pFonts) { CPDF_Dictionary* pElement = pFonts->GetDictFor(*csFontNameTag); if (pElement) { - CPDF_Font* pFont = - m_pField->GetForm()->GetDocument()->LoadFont(pElement); + CPDF_Font* pFont = m_pForm->GetDocument()->LoadFont(pElement); if (pFont) return pFont; } @@ -250,5 +246,5 @@ int CPDF_FormControl::GetControlAlignment() const { CPDF_Object* pObj = FPDF_GetFieldAttr(m_pField->GetDict(), "Q"); if (pObj) return pObj->GetInteger(); - return m_pField->GetForm()->GetFormAlignment(); + return m_pForm->GetFormAlignment(); } diff --git a/core/fpdfdoc/cpdf_formcontrol.h b/core/fpdfdoc/cpdf_formcontrol.h index 7288651a73..d66ae0ab6f 100644 --- a/core/fpdfdoc/cpdf_formcontrol.h +++ b/core/fpdfdoc/cpdf_formcontrol.h @@ -48,7 +48,7 @@ class CPDF_FormControl { const CPDF_InteractiveForm* GetInteractiveForm() const { return m_pForm.Get(); } - CPDF_FormField* GetField() const { return m_pField; } + CPDF_FormField* GetField() const { return m_pField.Get(); } CPDF_Dictionary* GetWidget() const { return m_pWidgetDict.Get(); } CFX_FloatRect GetRect() const; @@ -115,7 +115,7 @@ class CPDF_FormControl { CPDF_Stream* GetIcon(const ByteString& csEntry); CPDF_ApSettings GetMK() const; - CPDF_FormField* const m_pField; + UnownedPtr const m_pField; UnownedPtr const m_pWidgetDict; UnownedPtr const m_pForm; }; diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp index 4cb9496af9..2b06161b06 100644 --- a/core/fpdfdoc/cpdf_formfield.cpp +++ b/core/fpdfdoc/cpdf_formfield.cpp @@ -251,15 +251,20 @@ bool CPDF_FormField::ResetField(NotificationOption notify) { } int CPDF_FormField::CountControls() const { - return pdfium::CollectionSize(m_ControlList); + return pdfium::CollectionSize(GetControls()); +} + +CPDF_FormControl* CPDF_FormField::GetControl(int index) const { + return GetControls()[index].Get(); } int CPDF_FormField::GetControlIndex(const CPDF_FormControl* pControl) const { if (!pControl) return -1; - auto it = std::find(m_ControlList.begin(), m_ControlList.end(), pControl); - return it != m_ControlList.end() ? it - m_ControlList.begin() : -1; + const auto& controls = GetControls(); + auto it = std::find(controls.begin(), controls.end(), pControl); + return it != controls.end() ? it - controls.begin() : -1; } FormFieldType CPDF_FormField::GetFieldType() const { @@ -426,10 +431,11 @@ int CPDF_FormField::GetMaxLen() const { if (const CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "MaxLen")) return pObj->GetInteger(); - for (auto& pControl : m_ControlList) { + for (auto& pControl : GetControls()) { if (!pControl) continue; - CPDF_Dictionary* pWidgetDict = pControl->GetWidget(); + + const CPDF_Dictionary* pWidgetDict = pControl->GetWidget(); if (pWidgetDict->KeyExist("MaxLen")) return pWidgetDict->GetIntegerFor("MaxLen"); } @@ -931,3 +937,8 @@ void CPDF_FormField::NotifyListOrComboBoxAfterChange() { break; } } + +const std::vector>& CPDF_FormField::GetControls() + const { + return m_pForm->GetControlsForField(this); +} diff --git a/core/fpdfdoc/cpdf_formfield.h b/core/fpdfdoc/cpdf_formfield.h index ce12169a71..2c525cbdea 100644 --- a/core/fpdfdoc/cpdf_formfield.h +++ b/core/fpdfdoc/cpdf_formfield.h @@ -111,9 +111,7 @@ class CPDF_FormField { int CountControls() const; - CPDF_FormControl* GetControl(int index) const { - return m_ControlList[index].Get(); - } + CPDF_FormControl* GetControl(int index) const; int GetControlIndex(const CPDF_FormControl* pControl) const; FormFieldType GetFieldType() const; @@ -172,10 +170,6 @@ class CPDF_FormField { WideString GetCheckValue(bool bDefault) const; - void AddFormControl(CPDF_FormControl* pFormControl) { - m_ControlList.emplace_back(pFormControl); - } - void SetOpt(std::unique_ptr pOpt); private: @@ -197,6 +191,8 @@ class CPDF_FormField { bool NotifyListOrComboBoxBeforeChange(const WideString& value); void NotifyListOrComboBoxAfterChange(); + const std::vector>& GetControls() const; + CPDF_FormField::Type m_Type = kUnknown; uint32_t m_Flags = 0; bool m_bReadOnly = false; @@ -205,8 +201,6 @@ class CPDF_FormField { UnownedPtr const m_pForm; UnownedPtr const m_pDict; - // Owned by InteractiveForm parent. - std::vector> m_ControlList; float m_FontSize = 0; UnownedPtr m_pFont; }; diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp index 347fd559e0..754737c454 100644 --- a/core/fpdfdoc/cpdf_interactiveform.cpp +++ b/core/fpdfdoc/cpdf_interactiveform.cpp @@ -390,10 +390,10 @@ class CFieldTree { public: class Node { public: - Node() : m_pField(nullptr), m_level(0) {} + Node() : m_level(0) {} Node(const WideString& short_name, int level) : m_ShortName(short_name), m_level(level) {} - ~Node() {} + ~Node() = default; void AddChildNode(std::unique_ptr pNode) { m_Children.push_back(std::move(pNode)); @@ -466,9 +466,9 @@ class CFieldTree { Node m_Root; }; -CFieldTree::CFieldTree() {} +CFieldTree::CFieldTree() = default; -CFieldTree::~CFieldTree() {} +CFieldTree::~CFieldTree() = default; CFieldTree::Node* CFieldTree::AddChild(Node* pParent, const WideString& short_name) { @@ -717,7 +717,7 @@ CPDF_FormControl* CPDF_InteractiveForm::GetControlAtPoint( for (size_t i = pAnnotList->size(); i > 0; --i) { size_t annot_index = i - 1; - CPDF_Dictionary* pAnnot = pAnnotList->GetDictAt(annot_index); + const CPDF_Dictionary* pAnnot = pAnnotList->GetDictAt(annot_index); if (!pAnnot) continue; @@ -826,6 +826,13 @@ void CPDF_InteractiveForm::ResetForm(NotificationOption notify) { m_pFormNotify->AfterFormReset(this); } +const std::vector>& +CPDF_InteractiveForm::GetControlsForField(const CPDF_FormField* pField) const { + const auto& it = m_ControlLists.find(pField); + ASSERT(it != m_ControlLists.end()); + return it->second; +} + void CPDF_InteractiveForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel) { if (nLevel > nMaxRecursion) return; @@ -955,7 +962,7 @@ CPDF_FormControl* CPDF_InteractiveForm::AddControl( auto pNew = pdfium::MakeUnique(pField, pWidgetDict); CPDF_FormControl* pControl = pNew.get(); m_ControlMap[pWidgetDict] = std::move(pNew); - pField->AddFormControl(pControl); + m_ControlLists[pField].emplace_back(pControl); return pControl; } diff --git a/core/fpdfdoc/cpdf_interactiveform.h b/core/fpdfdoc/cpdf_interactiveform.h index 1b68852d48..7a89320692 100644 --- a/core/fpdfdoc/cpdf_interactiveform.h +++ b/core/fpdfdoc/cpdf_interactiveform.h @@ -91,6 +91,9 @@ class CPDF_InteractiveForm { CPDF_Document* GetDocument() const { return m_pDocument.Get(); } CPDF_Dictionary* GetFormDict() const { return m_pFormDict.Get(); } + const std::vector>& GetControlsForField( + const CPDF_FormField* pField) const; + private: void LoadField(CPDF_Dictionary* pFieldDict, int nLevel); void AddTerminalField(CPDF_Dictionary* pFieldDict); @@ -99,12 +102,15 @@ class CPDF_InteractiveForm { static bool s_bUpdateAP; + ByteString m_bsEncoding; UnownedPtr const m_pDocument; UnownedPtr m_pFormDict; + std::unique_ptr m_pFieldTree; std::map> m_ControlMap; - std::unique_ptr m_pFieldTree; - ByteString m_bsEncoding; + // Points into |m_ControlMap|. + std::map>> + m_ControlLists; UnownedPtr m_pFormNotify; }; -- cgit v1.2.3