Introduce new CXFA_FFWidget::As*() methods.
Enforce type safety at a small cost in performance since this
code has shown itself to be vulnerable to bad casting in the
historical past.
Change-Id: I6d543f446309326bac937d744c7b857fb0110e38
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/65455
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fxfa/cxfa_ffdropdown.cpp b/xfa/fxfa/cxfa_ffdropdown.cpp
index 9d610b1..4289dc1 100644
--- a/xfa/fxfa/cxfa_ffdropdown.cpp
+++ b/xfa/fxfa/cxfa_ffdropdown.cpp
@@ -13,3 +13,7 @@
CXFA_FFComboBox* CXFA_FFDropDown::AsComboBox() {
return nullptr;
}
+
+CXFA_FFDropDown* CXFA_FFDropDown::AsDropDown() {
+ return this;
+}
diff --git a/xfa/fxfa/cxfa_ffdropdown.h b/xfa/fxfa/cxfa_ffdropdown.h
index 45d30d9..b1751b4 100644
--- a/xfa/fxfa/cxfa_ffdropdown.h
+++ b/xfa/fxfa/cxfa_ffdropdown.h
@@ -16,6 +16,9 @@
public:
~CXFA_FFDropDown() override;
+ // CXFA_FFField:
+ CXFA_FFDropDown* AsDropDown() override;
+
virtual void InsertItem(const WideString& wsLabel, int32_t nIndex) = 0;
virtual void DeleteItem(int32_t nIndex) = 0;
virtual CXFA_FFComboBox* AsComboBox();
diff --git a/xfa/fxfa/cxfa_fffield.cpp b/xfa/fxfa/cxfa_fffield.cpp
index 692d13e..b031089 100644
--- a/xfa/fxfa/cxfa_fffield.cpp
+++ b/xfa/fxfa/cxfa_fffield.cpp
@@ -37,18 +37,18 @@
#include "xfa/fxgraphics/cxfa_gecolor.h"
#include "xfa/fxgraphics/cxfa_gepath.h"
-namespace {
-
-CXFA_FFField* ToField(CXFA_ContentLayoutItem* pItem) {
- return pItem ? static_cast<CXFA_FFField*>(pItem->GetFFWidget()) : nullptr;
-}
-
-} // namespace
-
CXFA_FFField::CXFA_FFField(CXFA_Node* pNode) : CXFA_FFWidget(pNode) {}
CXFA_FFField::~CXFA_FFField() = default;
+CXFA_FFDropDown* CXFA_FFField::AsDropDown() {
+ return nullptr;
+}
+
+CXFA_FFField* CXFA_FFField::AsField() {
+ return this;
+}
+
CFX_RectF CXFA_FFField::GetBBox(FocusOption focus) {
if (focus == kDoNotDrawFocus)
return CXFA_FFWidget::GetBBox(kDoNotDrawFocus);
@@ -160,13 +160,15 @@
}
float fScrollOffset = 0;
- CXFA_FFField* pPrev = ToField(GetLayoutItem()->GetPrev());
+ CXFA_ContentLayoutItem* pItem = GetLayoutItem()->GetPrev();
+ CXFA_FFField* pPrev = pItem ? ToField(pItem->GetFFWidget()) : nullptr;
if (pPrev)
fScrollOffset = -(m_pNode->GetUIMargin().top);
while (pPrev) {
fScrollOffset += pPrev->m_rtUI.height;
- pPrev = ToField(pPrev->GetLayoutItem()->GetPrev());
+ pItem = pPrev->GetLayoutItem()->GetPrev();
+ pPrev = pItem ? ToField(pItem->GetFFWidget()) : nullptr;
}
static_cast<CFWL_Edit*>(GetNormalWidget())->SetScrollOffset(fScrollOffset);
}
diff --git a/xfa/fxfa/cxfa_fffield.h b/xfa/fxfa/cxfa_fffield.h
index 47c0845..dd7b914 100644
--- a/xfa/fxfa/cxfa_fffield.h
+++ b/xfa/fxfa/cxfa_fffield.h
@@ -14,6 +14,7 @@
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
+class CXFA_FFDropDown;
class CXFA_Node;
#define XFA_MINUI_HEIGHT 4.32f
@@ -26,7 +27,10 @@
explicit CXFA_FFField(CXFA_Node* pNode);
~CXFA_FFField() override;
- // CXFA_FFWidget
+ virtual CXFA_FFDropDown* AsDropDown();
+
+ // CXFA_FFWidget:
+ CXFA_FFField* AsField() override;
CFX_RectF GetBBox(FocusOption focus) override;
void RenderWidget(CXFA_Graphics* pGS,
const CFX_Matrix& matrix,
@@ -57,7 +61,7 @@
bool OnSetCursor(const CFX_PointF& point) override;
FWL_WidgetHit HitTest(const CFX_PointF& point) override;
- // IFWL_WidgetDelegate
+ // IFWL_WidgetDelegate:
void OnProcessMessage(CFWL_Message* pMessage) override;
void OnProcessEvent(CFWL_Event* pEvent) override;
void OnDrawWidget(CXFA_Graphics* pGraphics,
@@ -105,4 +109,8 @@
std::unique_ptr<CFWL_Widget> m_pNormalWidget;
};
+inline CXFA_FFDropDown* ToDropDown(CXFA_FFField* field) {
+ return field ? field->AsDropDown() : nullptr;
+}
+
#endif // XFA_FXFA_CXFA_FFFIELD_H_
diff --git a/xfa/fxfa/cxfa_ffnotify.cpp b/xfa/fxfa/cxfa_ffnotify.cpp
index 4a9bfd3..fc70e6b 100644
--- a/xfa/fxfa/cxfa_ffnotify.cpp
+++ b/xfa/fxfa/cxfa_ffnotify.cpp
@@ -43,14 +43,6 @@
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_passwordedit.h"
-namespace {
-
-CXFA_FFDropDown* ToDropDown(CXFA_FFWidget* widget) {
- return static_cast<CXFA_FFDropDown*>(widget);
-}
-
-} // namespace
-
CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {}
CXFA_FFNotify::~CXFA_FFNotify() {}
@@ -71,7 +63,7 @@
CXFA_FFWidget* pWidget = m_pDoc->GetDocView()->GetWidgetForNode(pSender);
for (; pWidget; pWidget = pWidget->GetNextFFWidget()) {
if (pWidget->IsLoaded())
- ToDropDown(pWidget)->InsertItem(wsLabel, iIndex);
+ ToDropDown(ToField(pWidget))->InsertItem(wsLabel, iIndex);
}
}
@@ -83,7 +75,7 @@
CXFA_FFWidget* pWidget = m_pDoc->GetDocView()->GetWidgetForNode(pSender);
for (; pWidget; pWidget = pWidget->GetNextFFWidget()) {
if (pWidget->IsLoaded())
- ToDropDown(pWidget)->DeleteItem(iIndex);
+ ToDropDown(ToField(pWidget))->DeleteItem(iIndex);
}
}
@@ -268,7 +260,7 @@
if (!hWidget->IsLoaded())
return;
- CXFA_FFDropDown* pDropDown = ToDropDown(hWidget); // Safe if kChoiceList.
+ CXFA_FFDropDown* pDropDown = ToDropDown(ToField(hWidget));
CXFA_FFComboBox* pComboBox = ToComboBox(pDropDown);
if (!pComboBox)
return;
diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp
index b743a6e..881218c 100644
--- a/xfa/fxfa/cxfa_ffwidget.cpp
+++ b/xfa/fxfa/cxfa_ffwidget.cpp
@@ -288,6 +288,10 @@
GetLayoutItem()->SetStatusBits(dwAdded);
}
+CXFA_FFField* CXFA_FFWidget::AsField() {
+ return nullptr;
+}
+
CFX_RectF CXFA_FFWidget::GetBBox(FocusOption focus) {
if (focus == kDrawFocus || !m_pPageView)
return CFX_RectF();
diff --git a/xfa/fxfa/cxfa_ffwidget.h b/xfa/fxfa/cxfa_ffwidget.h
index c173f59..4c362c1 100644
--- a/xfa/fxfa/cxfa_ffwidget.h
+++ b/xfa/fxfa/cxfa_ffwidget.h
@@ -25,6 +25,7 @@
class CXFA_FFApp;
class CXFA_FFDoc;
class CXFA_FFDocView;
+class CXFA_FFField;
class CXFA_FFPageView;
class CXFA_FFWidgetHandler;
class CXFA_Graphics;
@@ -77,6 +78,8 @@
void DisplayCaret(bool bVisible, const CFX_RectF* pRtAnchor) override;
void GetBorderColorAndThickness(FX_ARGB* cr, float* fWidth) override;
+ virtual CXFA_FFField* AsField();
+
virtual CFX_RectF GetBBox(FocusOption focus);
virtual void RenderWidget(CXFA_Graphics* pGS,
const CFX_Matrix& matrix,
@@ -196,4 +199,8 @@
mutable CFX_RectF m_rtWidget;
};
+inline CXFA_FFField* ToField(CXFA_FFWidget* widget) {
+ return widget ? widget->AsField() : nullptr;
+}
+
#endif // XFA_FXFA_CXFA_FFWIDGET_H_