Use checked downcasts between CFXA_LayoutItem and CXFA_FFWidget.

Since not all CFXA_LayoutItems are CXFA_FFWidgets.
Move some conversion helpers to parent class while at it, and
use them in other places.

Bug: chromium:907430
Change-Id: I02f9f28be77dbf7e30baf7c7aed199a81401ca88
Reviewed-on: https://pdfium-review.googlesource.com/c/45850
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fxfa/cxfa_ffdocview.cpp b/xfa/fxfa/cxfa_ffdocview.cpp
index e4beae4..d90abef2 100644
--- a/xfa/fxfa/cxfa_ffdocview.cpp
+++ b/xfa/fxfa/cxfa_ffdocview.cpp
@@ -246,7 +246,7 @@
 }
 
 CXFA_FFWidget* CXFA_FFDocView::GetWidgetForNode(CXFA_Node* node) {
-  return static_cast<CXFA_FFWidget*>(GetXFALayout()->GetLayoutItem(node));
+  return ToFFWidget(ToContentLayoutItem(GetXFALayout()->GetLayoutItem(node)));
 }
 
 CXFA_FFWidgetHandler* CXFA_FFDocView::GetWidgetHandler() {
diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp
index 5a13c17..22eb621 100644
--- a/xfa/fxfa/cxfa_ffwidget.cpp
+++ b/xfa/fxfa/cxfa_ffwidget.cpp
@@ -224,9 +224,10 @@
 }
 
 CXFA_FFWidget* XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem* pLayoutItem) {
-  if (pLayoutItem->GetFormNode()->HasCreatedUIWidget())
-    return static_cast<CXFA_FFWidget*>(pLayoutItem);
-  return nullptr;
+  if (!pLayoutItem->GetFormNode()->HasCreatedUIWidget())
+    return nullptr;
+
+  return ToFFWidget(ToContentLayoutItem(pLayoutItem));
 }
 
 CXFA_CalcData::CXFA_CalcData() : m_iRefCount(0) {}
@@ -236,7 +237,11 @@
 CXFA_FFWidget::CXFA_FFWidget(CXFA_Node* node)
     : CXFA_ContentLayoutItem(node), m_pNode(node) {}
 
-CXFA_FFWidget::~CXFA_FFWidget() {}
+CXFA_FFWidget::~CXFA_FFWidget() = default;
+
+CXFA_FFWidget* CXFA_FFWidget::AsFFWidget() {
+  return this;
+}
 
 const CFWL_App* CXFA_FFWidget::GetFWLApp() {
   return GetPageView()->GetDocView()->GetDoc()->GetApp()->GetFWLApp();
@@ -398,10 +403,10 @@
 }
 
 bool CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget) {
-  CXFA_FFWidget* pParent = GetParent();
-  if (pParent && !pParent->IsAncestorOf(pOldWidget)) {
+  CXFA_FFWidget* pParent = ToFFWidget(ToContentLayoutItem(GetParent()));
+  if (pParent && !pParent->IsAncestorOf(pOldWidget))
     pParent->OnSetFocus(pOldWidget);
-  }
+
   m_dwStatus |= XFA_WidgetStatus_Focused;
   CXFA_EventParam eParam;
   eParam.m_eType = XFA_EVENT_Enter;
@@ -413,12 +418,13 @@
 bool CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) {
   m_dwStatus &= ~XFA_WidgetStatus_Focused;
   EventKillFocus();
-  if (pNewWidget) {
-    CXFA_FFWidget* pParent = GetParent();
-    if (pParent && !pParent->IsAncestorOf(pNewWidget)) {
-      pParent->OnKillFocus(pNewWidget);
-    }
-  }
+  if (!pNewWidget)
+    return true;
+
+  CXFA_FFWidget* pParent = ToFFWidget(ToContentLayoutItem(GetParent()));
+  if (pParent && !pParent->IsAncestorOf(pNewWidget))
+    pParent->OnKillFocus(pNewWidget);
+
   return true;
 }
 
@@ -557,13 +563,13 @@
   return rtLayout.width < 0.1f && rtLayout.height < 0.1f;
 }
 
-CXFA_FFWidget* CXFA_FFWidget::GetParent() {
+CXFA_LayoutItem* CXFA_FFWidget::GetParent() {
   CXFA_Node* pParentNode = m_pNode->GetParent();
-  if (pParentNode) {
-    CXFA_LayoutProcessor* layout = GetDocView()->GetXFALayout();
-    return static_cast<CXFA_FFWidget*>(layout->GetLayoutItem(pParentNode));
-  }
-  return nullptr;
+  if (!pParentNode)
+    return nullptr;
+
+  CXFA_LayoutProcessor* layout = GetDocView()->GetXFALayout();
+  return layout->GetLayoutItem(pParentNode);
 }
 
 bool CXFA_FFWidget::IsAncestorOf(CXFA_FFWidget* pWidget) {
diff --git a/xfa/fxfa/cxfa_ffwidget.h b/xfa/fxfa/cxfa_ffwidget.h
index 0d951d4..e9c991d 100644
--- a/xfa/fxfa/cxfa_ffwidget.h
+++ b/xfa/fxfa/cxfa_ffwidget.h
@@ -89,6 +89,9 @@
   explicit CXFA_FFWidget(CXFA_Node* pNode);
   ~CXFA_FFWidget() override;
 
+  // CXFA_ContentLayoutItem:
+  CXFA_FFWidget* AsFFWidget() override;
+
   virtual CFX_RectF GetBBox(uint32_t dwStatus, FocusOption focus);
   virtual void RenderWidget(CXFA_Graphics* pGS,
                             const CFX_Matrix& matrix,
@@ -162,7 +165,7 @@
   CFX_PointF Rotate2Normal(const CFX_PointF& point);
   CFX_Matrix GetRotateMatrix();
   bool IsLayoutRectEmpty();
-  CXFA_FFWidget* GetParent();
+  CXFA_LayoutItem* GetParent();
   bool IsAncestorOf(CXFA_FFWidget* pWidget);
   const CFWL_App* GetFWLApp();
 
diff --git a/xfa/fxfa/cxfa_ffwidgethandler.cpp b/xfa/fxfa/cxfa_ffwidgethandler.cpp
index 212a029..7cf36ff 100644
--- a/xfa/fxfa/cxfa_ffwidgethandler.cpp
+++ b/xfa/fxfa/cxfa_ffwidgethandler.cpp
@@ -276,7 +276,7 @@
   m_pDocView->RunLayout();
   CXFA_LayoutItem* pLayout =
       m_pDocView->GetXFALayout()->GetLayoutItem(pNewFormItem);
-  return static_cast<CXFA_FFWidget*>(pLayout);
+  return ToFFWidget(ToContentLayoutItem(pLayout));
 }
 
 CXFA_Node* CXFA_FFWidgetHandler::CreateWidgetFormItem(
diff --git a/xfa/fxfa/parser/cxfa_containerlayoutitem.h b/xfa/fxfa/parser/cxfa_containerlayoutitem.h
index 4a02333..c8cdf33 100644
--- a/xfa/fxfa/parser/cxfa_containerlayoutitem.h
+++ b/xfa/fxfa/parser/cxfa_containerlayoutitem.h
@@ -22,8 +22,4 @@
   UnownedPtr<CXFA_Node> m_pOldSubform;
 };
 
-inline CXFA_ContainerLayoutItem* ToContainerLayoutItem(CXFA_LayoutItem* pItem) {
-  return pItem ? pItem->AsContainerLayoutItem() : nullptr;
-}
-
 #endif  // XFA_FXFA_PARSER_CXFA_CONTAINERLAYOUTITEM_H_
diff --git a/xfa/fxfa/parser/cxfa_contentlayoutitem.cpp b/xfa/fxfa/parser/cxfa_contentlayoutitem.cpp
index b3ceb9e..6878c8e 100644
--- a/xfa/fxfa/parser/cxfa_contentlayoutitem.cpp
+++ b/xfa/fxfa/parser/cxfa_contentlayoutitem.cpp
@@ -18,6 +18,10 @@
     m_pFormNode->JSObject()->SetLayoutItem(nullptr);
 }
 
+CXFA_FFWidget* CXFA_ContentLayoutItem::AsFFWidget() {
+  return nullptr;
+}
+
 CXFA_ContentLayoutItem* CXFA_ContentLayoutItem::GetFirst() {
   CXFA_ContentLayoutItem* pCurNode = this;
   while (pCurNode->m_pPrev)
diff --git a/xfa/fxfa/parser/cxfa_contentlayoutitem.h b/xfa/fxfa/parser/cxfa_contentlayoutitem.h
index fc91f3b..ac2d8f2 100644
--- a/xfa/fxfa/parser/cxfa_contentlayoutitem.h
+++ b/xfa/fxfa/parser/cxfa_contentlayoutitem.h
@@ -9,11 +9,15 @@
 
 #include "xfa/fxfa/parser/cxfa_layoutitem.h"
 
+class CXFA_FFWidget;
+
 class CXFA_ContentLayoutItem : public CXFA_LayoutItem {
  public:
   explicit CXFA_ContentLayoutItem(CXFA_Node* pNode);
   ~CXFA_ContentLayoutItem() override;
 
+  virtual CXFA_FFWidget* AsFFWidget();
+
   CXFA_ContentLayoutItem* GetFirst();
   CXFA_ContentLayoutItem* GetLast();
   CXFA_ContentLayoutItem* GetPrev() const { return m_pPrev; }
@@ -30,8 +34,8 @@
   mutable uint32_t m_dwStatus = 0;
 };
 
-inline CXFA_ContentLayoutItem* ToContentLayoutItem(CXFA_LayoutItem* pItem) {
-  return pItem ? pItem->AsContentLayoutItem() : nullptr;
+inline CXFA_FFWidget* ToFFWidget(CXFA_ContentLayoutItem* item) {
+  return item ? item->AsFFWidget() : nullptr;
 }
 
 #endif  // XFA_FXFA_PARSER_CXFA_CONTENTLAYOUTITEM_H_
diff --git a/xfa/fxfa/parser/cxfa_layoutitem.h b/xfa/fxfa/parser/cxfa_layoutitem.h
index c9b2859..3426a83 100644
--- a/xfa/fxfa/parser/cxfa_layoutitem.h
+++ b/xfa/fxfa/parser/cxfa_layoutitem.h
@@ -45,6 +45,14 @@
   UnownedPtr<CXFA_Node> m_pFormNode;
 };
 
+inline CXFA_ContainerLayoutItem* ToContainerLayoutItem(CXFA_LayoutItem* item) {
+  return item ? item->AsContainerLayoutItem() : nullptr;
+}
+
+inline CXFA_ContentLayoutItem* ToContentLayoutItem(CXFA_LayoutItem* item) {
+  return item ? item->AsContentLayoutItem() : nullptr;
+}
+
 void XFA_ReleaseLayoutItem(CXFA_LayoutItem* pLayoutItem);
 
 #endif  // XFA_FXFA_PARSER_CXFA_LAYOUTITEM_H_
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 4b49f61..e4899bd 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -2747,7 +2747,7 @@
 }
 
 CXFA_FFWidget* CXFA_Node::GetNextWidget(CXFA_FFWidget* pWidget) {
-  return static_cast<CXFA_FFWidget*>(pWidget->GetNext());
+  return ToFFWidget(pWidget->GetNext());
 }
 
 void CXFA_Node::UpdateUIDisplay(CXFA_FFDocView* docView,
diff --git a/xfa/fxfa/parser/cxfa_traversestrategy_contentareacontainerlayoutitem.h b/xfa/fxfa/parser/cxfa_traversestrategy_contentareacontainerlayoutitem.h
index e0a584e..154d7d9 100644
--- a/xfa/fxfa/parser/cxfa_traversestrategy_contentareacontainerlayoutitem.h
+++ b/xfa/fxfa/parser/cxfa_traversestrategy_contentareacontainerlayoutitem.h
@@ -37,7 +37,7 @@
 
   static CXFA_ContainerLayoutItem* GetParent(
       CXFA_ContainerLayoutItem* pLayoutItem) {
-    return static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pParent);
+    return ToContainerLayoutItem(pLayoutItem->m_pParent);
   }
 };