Split fpdfsdk/fsdk_baseform.h into individual classes.

This CL moves classes in fsdk_baseform.h to their own files.
Classes include CPDFSDK_Widget, CBA_AnnotIterator, CPDFSDK_XFAWidget,
PDFSDK_FieldAction, and CPDFSDK_Interform.

Review-Url: https://codereview.chromium.org/2252723002
diff --git a/BUILD.gn b/BUILD.gn
index 1969a4b..b69fb70 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -62,6 +62,7 @@
 
 static_library("pdfium") {
   sources = [
+    "fpdfsdk/cba_annotiterator.cpp",
     "fpdfsdk/cfx_systemhandler.cpp",
     "fpdfsdk/cfx_systemhandler.h",
     "fpdfsdk/cpdfsdk_annot.cpp",
@@ -70,6 +71,8 @@
     "fpdfsdk/cpdfsdk_baannot.cpp",
     "fpdfsdk/cpdfsdk_bfannothandler.cpp",
     "fpdfsdk/cpdfsdk_datetime.cpp",
+    "fpdfsdk/cpdfsdk_interform.cpp",
+    "fpdfsdk/cpdfsdk_widget.cpp",
     "fpdfsdk/cpdfsdk_xfaannothandler.cpp",
     "fpdfsdk/fpdf_dataavail.cpp",
     "fpdfsdk/fpdf_ext.cpp",
@@ -87,20 +90,23 @@
     "fpdfsdk/fpdftext.cpp",
     "fpdfsdk/fpdfview.cpp",
     "fpdfsdk/fsdk_actionhandler.cpp",
-    "fpdfsdk/fsdk_baseform.cpp",
     "fpdfsdk/fsdk_mgr.cpp",
     "fpdfsdk/fsdk_pauseadapter.cpp",
+    "fpdfsdk/include/cba_annotiterator.h",
     "fpdfsdk/include/cpdfsdk_annot.h",
     "fpdfsdk/include/cpdfsdk_annothandlermgr.h",
     "fpdfsdk/include/cpdfsdk_annotiterator.h",
     "fpdfsdk/include/cpdfsdk_baannot.h",
     "fpdfsdk/include/cpdfsdk_bfannothandler.h",
     "fpdfsdk/include/cpdfsdk_datetime.h",
+    "fpdfsdk/include/cpdfsdk_interform.h",
+    "fpdfsdk/include/cpdfsdk_widget.h",
     "fpdfsdk/include/cpdfsdk_xfaannothandler.h",
     "fpdfsdk/include/fsdk_actionhandler.h",
-    "fpdfsdk/include/fsdk_baseform.h",
     "fpdfsdk/include/fsdk_pauseadapter.h",
     "fpdfsdk/include/ifpdfsdk_annothandler.h",
+    "fpdfsdk/include/pdfsdk_fieldaction.h",
+    "fpdfsdk/pdfsdk_fieldaction.cpp",
     "public/fpdf_dataavail.h",
     "public/fpdf_doc.h",
     "public/fpdf_edit.h",
@@ -138,6 +144,11 @@
   ]
 
   if (pdf_enable_xfa) {
+    sources += [
+      "fpdfsdk/cpdfsdk_xfawidget.cpp",
+      "fpdfsdk/include/cpdfsdk_xfawidget.h",
+    ]
+
     deps += [ ":fpdfxfa" ]
   }
 
diff --git a/fpdfsdk/cba_annotiterator.cpp b/fpdfsdk/cba_annotiterator.cpp
new file mode 100644
index 0000000..f07805e
--- /dev/null
+++ b/fpdfsdk/cba_annotiterator.cpp
@@ -0,0 +1,174 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/include/cba_annotiterator.h"
+
+#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
+#include "fpdfsdk/include/cpdfsdk_annot.h"
+#include "fpdfsdk/include/fsdk_mgr.h"
+
+// static
+bool CBA_AnnotIterator::CompareByLeftAscending(const CPDFSDK_Annot* p1,
+                                               const CPDFSDK_Annot* p2) {
+  return GetAnnotRect(p1).left < GetAnnotRect(p2).left;
+}
+
+// static
+bool CBA_AnnotIterator::CompareByTopDescending(const CPDFSDK_Annot* p1,
+                                               const CPDFSDK_Annot* p2) {
+  return GetAnnotRect(p1).top > GetAnnotRect(p2).top;
+}
+
+CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView,
+                                     const CFX_ByteString& sType,
+                                     const CFX_ByteString& sSubType)
+    : m_eTabOrder(STRUCTURE),
+      m_pPageView(pPageView),
+      m_sType(sType),
+      m_sSubType(sSubType) {
+  CPDF_Page* pPDFPage = m_pPageView->GetPDFPage();
+  CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetStringBy("Tabs");
+  if (sTabs == "R")
+    m_eTabOrder = ROW;
+  else if (sTabs == "C")
+    m_eTabOrder = COLUMN;
+
+  GenerateResults();
+}
+
+CBA_AnnotIterator::~CBA_AnnotIterator() {}
+
+CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() {
+  return m_Annots.empty() ? nullptr : m_Annots.front();
+}
+
+CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() {
+  return m_Annots.empty() ? nullptr : m_Annots.back();
+}
+
+CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) {
+  auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot);
+  if (iter == m_Annots.end())
+    return nullptr;
+  ++iter;
+  if (iter == m_Annots.end())
+    iter = m_Annots.begin();
+  return *iter;
+}
+
+CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) {
+  auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot);
+  if (iter == m_Annots.end())
+    return nullptr;
+  if (iter == m_Annots.begin())
+    iter = m_Annots.end();
+  return *(--iter);
+}
+
+void CBA_AnnotIterator::GenerateResults() {
+  switch (m_eTabOrder) {
+    case STRUCTURE: {
+      for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
+        CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
+        if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
+          m_Annots.push_back(pAnnot);
+      }
+      break;
+    }
+    case ROW: {
+      std::vector<CPDFSDK_Annot*> sa;
+      for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
+        CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
+        if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
+          sa.push_back(pAnnot);
+      }
+
+      std::sort(sa.begin(), sa.end(), CompareByLeftAscending);
+      while (!sa.empty()) {
+        int nLeftTopIndex = -1;
+        FX_FLOAT fTop = 0.0f;
+        for (int i = sa.size() - 1; i >= 0; i--) {
+          CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
+          if (rcAnnot.top > fTop) {
+            nLeftTopIndex = i;
+            fTop = rcAnnot.top;
+          }
+        }
+        if (nLeftTopIndex >= 0) {
+          CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex];
+          CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
+          m_Annots.push_back(pLeftTopAnnot);
+          sa.erase(sa.begin() + nLeftTopIndex);
+
+          std::vector<int> aSelect;
+          for (size_t i = 0; i < sa.size(); ++i) {
+            CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
+            FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f;
+            if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top)
+              aSelect.push_back(i);
+          }
+          for (size_t i = 0; i < aSelect.size(); ++i)
+            m_Annots.push_back(sa[aSelect[i]]);
+
+          for (int i = aSelect.size() - 1; i >= 0; --i)
+            sa.erase(sa.begin() + aSelect[i]);
+        }
+      }
+      break;
+    }
+    case COLUMN: {
+      std::vector<CPDFSDK_Annot*> sa;
+      for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
+        CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
+        if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
+          sa.push_back(pAnnot);
+      }
+
+      std::sort(sa.begin(), sa.end(), CompareByTopDescending);
+      while (!sa.empty()) {
+        int nLeftTopIndex = -1;
+        FX_FLOAT fLeft = -1.0f;
+        for (int i = sa.size() - 1; i >= 0; --i) {
+          CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
+          if (fLeft < 0) {
+            nLeftTopIndex = 0;
+            fLeft = rcAnnot.left;
+          } else if (rcAnnot.left < fLeft) {
+            nLeftTopIndex = i;
+            fLeft = rcAnnot.left;
+          }
+        }
+
+        if (nLeftTopIndex >= 0) {
+          CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex];
+          CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
+          m_Annots.push_back(pLeftTopAnnot);
+          sa.erase(sa.begin() + nLeftTopIndex);
+
+          std::vector<int> aSelect;
+          for (size_t i = 0; i < sa.size(); ++i) {
+            CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
+            FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f;
+            if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right)
+              aSelect.push_back(i);
+          }
+          for (size_t i = 0; i < aSelect.size(); ++i)
+            m_Annots.push_back(sa[aSelect[i]]);
+
+          for (int i = aSelect.size() - 1; i >= 0; --i)
+            sa.erase(sa.begin() + aSelect[i]);
+        }
+      }
+      break;
+    }
+  }
+}
+
+CFX_FloatRect CBA_AnnotIterator::GetAnnotRect(const CPDFSDK_Annot* pAnnot) {
+  CFX_FloatRect rcAnnot;
+  pAnnot->GetPDFAnnot()->GetRect(rcAnnot);
+  return rcAnnot;
+}
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.cpp b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
index c3fac48..bca2c9b 100644
--- a/fpdfsdk/cpdfsdk_annothandlermgr.cpp
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
@@ -7,6 +7,7 @@
 #include "fpdfsdk/include/cpdfsdk_annothandlermgr.h"
 
 #include "core/fpdfdoc/include/cpdf_annot.h"
+#include "fpdfsdk/include/cba_annotiterator.h"
 #include "fpdfsdk/include/cpdfsdk_annot.h"
 #include "fpdfsdk/include/cpdfsdk_baannot.h"
 #include "fpdfsdk/include/cpdfsdk_bfannothandler.h"
diff --git a/fpdfsdk/cpdfsdk_bfannothandler.cpp b/fpdfsdk/cpdfsdk_bfannothandler.cpp
index a9a8c4b..0617e44 100644
--- a/fpdfsdk/cpdfsdk_bfannothandler.cpp
+++ b/fpdfsdk/cpdfsdk_bfannothandler.cpp
@@ -14,6 +14,8 @@
 #include "core/fpdfdoc/include/cpdf_interform.h"
 #include "fpdfsdk/formfiller/cffl_formfiller.h"
 #include "fpdfsdk/include/cpdfsdk_annot.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 
 #ifdef PDF_ENABLE_XFA
diff --git a/fpdfsdk/cpdfsdk_interform.cpp b/fpdfsdk/cpdfsdk_interform.cpp
new file mode 100644
index 0000000..65e778d
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_interform.cpp
@@ -0,0 +1,726 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/include/cpdfsdk_interform.h"
+
+#include <algorithm>
+#include <memory>
+
+#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
+#include "core/fpdfapi/fpdf_parser/include/cfdf_document.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
+#include "core/fpdfdoc/include/cpdf_actionfields.h"
+#include "core/fpdfdoc/include/cpdf_interform.h"
+#include "core/fxge/include/cfx_graphstatedata.h"
+#include "core/fxge/include/cfx_pathdata.h"
+#include "core/fxge/include/cfx_renderdevice.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/fxedit/include/fxet_edit.h"
+#include "fpdfsdk/include/cba_annotiterator.h"
+#include "fpdfsdk/include/cpdfsdk_annot.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
+#include "fpdfsdk/include/fsdk_actionhandler.h"
+#include "fpdfsdk/include/fsdk_define.h"
+#include "fpdfsdk/include/fsdk_mgr.h"
+#include "fpdfsdk/include/ipdfsdk_annothandler.h"
+#include "fpdfsdk/javascript/ijs_context.h"
+#include "fpdfsdk/javascript/ijs_runtime.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+#include "third_party/base/stl_util.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h"
+#include "fpdfsdk/fpdfxfa/include/fpdfxfa_util.h"
+#include "fpdfsdk/include/cpdfsdk_xfawidget.h"
+#include "xfa/fxfa/include/cxfa_eventparam.h"
+#include "xfa/fxfa/include/xfa_ffdocview.h"
+#include "xfa/fxfa/include/xfa_ffwidget.h"
+#include "xfa/fxfa/include/xfa_ffwidgethandler.h"
+#endif  // PDF_ENABLE_XFA
+
+CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument)
+    : m_pDocument(pDocument),
+      m_pInterForm(new CPDF_InterForm(m_pDocument->GetPDFDocument())),
+#ifdef PDF_ENABLE_XFA
+      m_bXfaCalculate(TRUE),
+      m_bXfaValidationsEnabled(TRUE),
+#endif  // PDF_ENABLE_XFA
+      m_bCalculate(TRUE),
+      m_bBusy(FALSE),
+      m_iHighlightAlpha(0) {
+  m_pInterForm->SetFormNotify(this);
+  for (int i = 0; i < kNumFieldTypes; ++i)
+    m_bNeedHightlight[i] = FALSE;
+}
+
+CPDFSDK_InterForm::~CPDFSDK_InterForm() {
+  m_Map.clear();
+#ifdef PDF_ENABLE_XFA
+  m_XFAMap.clear();
+#endif  // PDF_ENABLE_XFA
+}
+
+FX_BOOL CPDFSDK_InterForm::HighlightWidgets() {
+  return FALSE;
+}
+
+CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget,
+                                              FX_BOOL bNext) const {
+  std::unique_ptr<CBA_AnnotIterator> pIterator(
+      new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", ""));
+
+  if (bNext)
+    return static_cast<CPDFSDK_Widget*>(pIterator->GetNextAnnot(pWidget));
+
+  return static_cast<CPDFSDK_Widget*>(pIterator->GetPrevAnnot(pWidget));
+}
+
+CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl,
+                                             bool createIfNeeded) const {
+  if (!pControl || !m_pInterForm)
+    return nullptr;
+
+  CPDFSDK_Widget* pWidget = nullptr;
+  const auto it = m_Map.find(pControl);
+  if (it != m_Map.end())
+    pWidget = it->second;
+  if (pWidget)
+    return pWidget;
+  if (!createIfNeeded)
+    return nullptr;
+
+  CPDF_Dictionary* pControlDict = pControl->GetWidget();
+  CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
+  CPDFSDK_PageView* pPage = nullptr;
+
+  if (CPDF_Dictionary* pPageDict = pControlDict->GetDictBy("P")) {
+    int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
+    if (nPageIndex >= 0)
+      pPage = m_pDocument->GetPageView(nPageIndex);
+  }
+
+  if (!pPage) {
+    int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
+    if (nPageIndex >= 0)
+      pPage = m_pDocument->GetPageView(nPageIndex);
+  }
+
+  if (!pPage)
+    return nullptr;
+
+  return static_cast<CPDFSDK_Widget*>(pPage->GetAnnotByDict(pControlDict));
+}
+
+void CPDFSDK_InterForm::GetWidgets(
+    const CFX_WideString& sFieldName,
+    std::vector<CPDFSDK_Widget*>* widgets) const {
+  for (int i = 0, sz = m_pInterForm->CountFields(sFieldName); i < sz; ++i) {
+    CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName);
+    ASSERT(pFormField);
+    GetWidgets(pFormField, widgets);
+  }
+}
+
+void CPDFSDK_InterForm::GetWidgets(
+    CPDF_FormField* pField,
+    std::vector<CPDFSDK_Widget*>* widgets) const {
+  for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
+    CPDF_FormControl* pFormCtrl = pField->GetControl(i);
+    ASSERT(pFormCtrl);
+    CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, true);
+    if (pWidget)
+      widgets->push_back(pWidget);
+  }
+}
+
+int CPDFSDK_InterForm::GetPageIndexByAnnotDict(
+    CPDF_Document* pDocument,
+    CPDF_Dictionary* pAnnotDict) const {
+  ASSERT(pAnnotDict);
+
+  for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) {
+    if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i)) {
+      if (CPDF_Array* pAnnots = pPageDict->GetArrayBy("Annots")) {
+        for (int j = 0, jsz = pAnnots->GetCount(); j < jsz; j++) {
+          CPDF_Object* pDict = pAnnots->GetDirectObjectAt(j);
+          if (pAnnotDict == pDict)
+            return i;
+        }
+      }
+    }
+  }
+
+  return -1;
+}
+
+void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl,
+                               CPDFSDK_Widget* pWidget) {
+  m_Map[pControl] = pWidget;
+}
+
+void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl) {
+  m_Map.erase(pControl);
+}
+
+void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled) {
+  m_bCalculate = bEnabled;
+}
+
+FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const {
+  return m_bCalculate;
+}
+
+#ifdef PDF_ENABLE_XFA
+void CPDFSDK_InterForm::AddXFAMap(CXFA_FFWidget* hWidget,
+                                  CPDFSDK_XFAWidget* pWidget) {
+  ASSERT(hWidget);
+  m_XFAMap[hWidget] = pWidget;
+}
+
+void CPDFSDK_InterForm::RemoveXFAMap(CXFA_FFWidget* hWidget) {
+  ASSERT(hWidget);
+  m_XFAMap.erase(hWidget);
+}
+
+CPDFSDK_XFAWidget* CPDFSDK_InterForm::GetXFAWidget(CXFA_FFWidget* hWidget) {
+  ASSERT(hWidget);
+  auto it = m_XFAMap.find(hWidget);
+  return it != m_XFAMap.end() ? it->second : nullptr;
+}
+
+void CPDFSDK_InterForm::XfaEnableCalculate(FX_BOOL bEnabled) {
+  m_bXfaCalculate = bEnabled;
+}
+FX_BOOL CPDFSDK_InterForm::IsXfaCalculateEnabled() const {
+  return m_bXfaCalculate;
+}
+
+FX_BOOL CPDFSDK_InterForm::IsXfaValidationsEnabled() {
+  return m_bXfaValidationsEnabled;
+}
+void CPDFSDK_InterForm::XfaSetValidationsEnabled(FX_BOOL bEnabled) {
+  m_bXfaValidationsEnabled = bEnabled;
+}
+
+void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField,
+                                         FX_BOOL bSynchronizeElse) {
+  for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
+    CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
+    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false))
+      pWidget->Synchronize(bSynchronizeElse);
+  }
+}
+#endif  // PDF_ENABLE_XFA
+
+void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) {
+  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
+  ASSERT(pEnv);
+  if (!pEnv->IsJSInitiated())
+    return;
+
+  if (m_bBusy)
+    return;
+
+  m_bBusy = TRUE;
+
+  if (!IsCalculateEnabled()) {
+    m_bBusy = FALSE;
+    return;
+  }
+
+  IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
+  pRuntime->SetReaderDocument(m_pDocument);
+
+  int nSize = m_pInterForm->CountFieldsInCalculationOrder();
+  for (int i = 0; i < nSize; i++) {
+    CPDF_FormField* pField = m_pInterForm->GetFieldInCalculationOrder(i);
+    if (!pField)
+      continue;
+
+    int nType = pField->GetFieldType();
+    if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD)
+      continue;
+
+    CPDF_AAction aAction = pField->GetAdditionalAction();
+    if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::Calculate))
+      continue;
+
+    CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate);
+    if (!action.GetDict())
+      continue;
+
+    CFX_WideString csJS = action.GetJavaScript();
+    if (csJS.IsEmpty())
+      continue;
+
+    IJS_Context* pContext = pRuntime->NewContext();
+    CFX_WideString sOldValue = pField->GetValue();
+    CFX_WideString sValue = sOldValue;
+    FX_BOOL bRC = TRUE;
+    pContext->OnField_Calculate(pFormField, pField, sValue, bRC);
+
+    CFX_WideString sInfo;
+    FX_BOOL bRet = pContext->RunScript(csJS, &sInfo);
+    pRuntime->ReleaseContext(pContext);
+
+    if (bRet && bRC && sValue.Compare(sOldValue) != 0)
+      pField->SetValue(sValue, TRUE);
+  }
+
+  m_bBusy = FALSE;
+}
+
+CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField,
+                                           FX_BOOL& bFormated) {
+  CFX_WideString sValue = pFormField->GetValue();
+  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
+  ASSERT(pEnv);
+  if (!pEnv->IsJSInitiated()) {
+    bFormated = FALSE;
+    return sValue;
+  }
+
+  IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
+  pRuntime->SetReaderDocument(m_pDocument);
+
+  if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX &&
+      pFormField->CountSelectedItems() > 0) {
+    int index = pFormField->GetSelectedIndex(0);
+    if (index >= 0)
+      sValue = pFormField->GetOptionLabel(index);
+  }
+
+  bFormated = FALSE;
+
+  CPDF_AAction aAction = pFormField->GetAdditionalAction();
+  if (aAction.GetDict() && aAction.ActionExist(CPDF_AAction::Format)) {
+    CPDF_Action action = aAction.GetAction(CPDF_AAction::Format);
+    if (action.GetDict()) {
+      CFX_WideString script = action.GetJavaScript();
+      if (!script.IsEmpty()) {
+        CFX_WideString Value = sValue;
+
+        IJS_Context* pContext = pRuntime->NewContext();
+        pContext->OnField_Format(pFormField, Value, TRUE);
+        CFX_WideString sInfo;
+        FX_BOOL bRet = pContext->RunScript(script, &sInfo);
+        pRuntime->ReleaseContext(pContext);
+
+        if (bRet) {
+          sValue = Value;
+          bFormated = TRUE;
+        }
+      }
+    }
+  }
+
+  return sValue;
+}
+
+void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField,
+                                             const FX_WCHAR* sValue,
+                                             FX_BOOL bValueChanged) {
+  for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
+    CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
+    ASSERT(pFormCtrl);
+    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false))
+      pWidget->ResetAppearance(sValue, bValueChanged);
+  }
+}
+
+void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) {
+  for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
+    CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
+    ASSERT(pFormCtrl);
+
+    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) {
+      CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
+      CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller();
+      UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
+      CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage, false);
+      FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget);
+
+      pEnv->FFI_Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right,
+                           rcBBox.bottom);
+    }
+  }
+}
+
+FX_BOOL CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField,
+                                             const CFX_WideString& csValue) {
+  CPDF_AAction aAction = pFormField->GetAdditionalAction();
+  if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::KeyStroke))
+    return TRUE;
+
+  CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke);
+  if (!action.GetDict())
+    return TRUE;
+
+  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
+  CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
+  PDFSDK_FieldAction fa;
+  fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
+  fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
+  fa.sValue = csValue;
+  pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke,
+                                           m_pDocument, pFormField, fa);
+  return fa.bRC;
+}
+
+FX_BOOL CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField,
+                                      const CFX_WideString& csValue) {
+  CPDF_AAction aAction = pFormField->GetAdditionalAction();
+  if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::Validate))
+    return TRUE;
+
+  CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate);
+  if (!action.GetDict())
+    return TRUE;
+
+  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
+  CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
+  PDFSDK_FieldAction fa;
+  fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
+  fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
+  fa.sValue = csValue;
+  pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate,
+                                           m_pDocument, pFormField, fa);
+  return fa.bRC;
+}
+
+FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action) {
+  ASSERT(action.GetDict());
+
+  CPDF_ActionFields af(&action);
+  std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
+  std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
+
+  bool bHide = action.GetHideStatus();
+  FX_BOOL bChanged = FALSE;
+
+  for (CPDF_FormField* pField : fields) {
+    for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
+      CPDF_FormControl* pControl = pField->GetControl(i);
+      ASSERT(pControl);
+
+      if (CPDFSDK_Widget* pWidget = GetWidget(pControl, false)) {
+        uint32_t nFlags = pWidget->GetFlags();
+        nFlags &= ~ANNOTFLAG_INVISIBLE;
+        nFlags &= ~ANNOTFLAG_NOVIEW;
+        if (bHide)
+          nFlags |= ANNOTFLAG_HIDDEN;
+        else
+          nFlags &= ~ANNOTFLAG_HIDDEN;
+        pWidget->SetFlags(nFlags);
+        pWidget->GetPageView()->UpdateView(pWidget);
+        bChanged = TRUE;
+      }
+    }
+  }
+
+  return bChanged;
+}
+
+FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action) {
+  CFX_WideString sDestination = action.GetFilePath();
+  if (sDestination.IsEmpty())
+    return FALSE;
+
+  CPDF_Dictionary* pActionDict = action.GetDict();
+  if (pActionDict->KeyExist("Fields")) {
+    CPDF_ActionFields af(&action);
+    uint32_t dwFlags = action.GetFlags();
+    std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
+    std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
+    if (!fields.empty()) {
+      bool bIncludeOrExclude = !(dwFlags & 0x01);
+      if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude))
+        return FALSE;
+
+      return SubmitFields(sDestination, fields, bIncludeOrExclude, false);
+    }
+  }
+  if (m_pInterForm->CheckRequiredFields(nullptr, true))
+    return FALSE;
+
+  return SubmitForm(sDestination, FALSE);
+}
+
+FX_BOOL CPDFSDK_InterForm::SubmitFields(
+    const CFX_WideString& csDestination,
+    const std::vector<CPDF_FormField*>& fields,
+    bool bIncludeOrExclude,
+    bool bUrlEncoded) {
+  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
+
+  CFX_ByteTextBuf textBuf;
+  ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf);
+
+  uint8_t* pBuffer = textBuf.GetBuffer();
+  FX_STRSIZE nBufSize = textBuf.GetLength();
+
+  if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize))
+    return FALSE;
+
+  pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str());
+  return TRUE;
+}
+
+FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile,
+                                               CFX_WideString csTxtFile) {
+  return TRUE;
+}
+
+FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf,
+                                               FX_STRSIZE& nBufSize) {
+  CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize);
+  if (!pFDF)
+    return TRUE;
+
+  CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDictBy("FDF");
+  if (!pMainDict)
+    return FALSE;
+
+  CPDF_Array* pFields = pMainDict->GetArrayBy("Fields");
+  if (!pFields)
+    return FALSE;
+
+  CFX_ByteTextBuf fdfEncodedData;
+  for (uint32_t i = 0; i < pFields->GetCount(); i++) {
+    CPDF_Dictionary* pField = pFields->GetDictAt(i);
+    if (!pField)
+      continue;
+    CFX_WideString name;
+    name = pField->GetUnicodeTextBy("T");
+    CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
+    CFX_ByteString csBValue = pField->GetStringBy("V");
+    CFX_WideString csWValue = PDF_DecodeText(csBValue);
+    CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue);
+
+    fdfEncodedData << name_b.GetBuffer(name_b.GetLength());
+    name_b.ReleaseBuffer();
+    fdfEncodedData << "=";
+    fdfEncodedData << csValue_b.GetBuffer(csValue_b.GetLength());
+    csValue_b.ReleaseBuffer();
+    if (i != pFields->GetCount() - 1)
+      fdfEncodedData << "&";
+  }
+
+  nBufSize = fdfEncodedData.GetLength();
+  pBuf = FX_Alloc(uint8_t, nBufSize);
+  FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize);
+  return TRUE;
+}
+
+FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf(
+    const std::vector<CPDF_FormField*>& fields,
+    bool bIncludeOrExclude,
+    CFX_ByteTextBuf& textBuf) {
+  std::unique_ptr<CFDF_Document> pFDF(m_pInterForm->ExportToFDF(
+      m_pDocument->GetPath().AsStringC(), fields, bIncludeOrExclude));
+  return pFDF ? pFDF->WriteBuf(textBuf) : FALSE;
+}
+
+CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(
+    const CFX_WideString& sFileExt) {
+  return L"";
+}
+
+FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination,
+                                      FX_BOOL bUrlEncoded) {
+  if (sDestination.IsEmpty())
+    return FALSE;
+
+  if (!m_pDocument || !m_pInterForm)
+    return FALSE;
+
+  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
+  CFX_WideString wsPDFFilePath = m_pDocument->GetPath();
+  CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath.AsStringC());
+  if (!pFDFDoc)
+    return FALSE;
+
+  CFX_ByteTextBuf FdfBuffer;
+  FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer);
+  delete pFDFDoc;
+  if (!bRet)
+    return FALSE;
+
+  uint8_t* pBuffer = FdfBuffer.GetBuffer();
+  FX_STRSIZE nBufSize = FdfBuffer.GetLength();
+
+  if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize))
+    return FALSE;
+
+  pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str());
+
+  if (bUrlEncoded)
+    FX_Free(pBuffer);
+
+  return TRUE;
+}
+
+FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) {
+  CFDF_Document* pFDF =
+      m_pInterForm->ExportToFDF(m_pDocument->GetPath().AsStringC());
+  if (!pFDF)
+    return FALSE;
+
+  FX_BOOL bRet = pFDF->WriteBuf(textBuf);
+  delete pFDF;
+
+  return bRet;
+}
+
+FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action) {
+  ASSERT(action.GetDict());
+
+  CPDF_Dictionary* pActionDict = action.GetDict();
+  if (!pActionDict->KeyExist("Fields"))
+    return m_pInterForm->ResetForm(true);
+
+  CPDF_ActionFields af(&action);
+  uint32_t dwFlags = action.GetFlags();
+
+  std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
+  std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
+  return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), true);
+}
+
+FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action) {
+  return FALSE;
+}
+
+std::vector<CPDF_FormField*> CPDFSDK_InterForm::GetFieldFromObjects(
+    const std::vector<CPDF_Object*>& objects) const {
+  std::vector<CPDF_FormField*> fields;
+  for (CPDF_Object* pObject : objects) {
+    if (pObject && pObject->IsString()) {
+      CFX_WideString csName = pObject->GetUnicodeText();
+      CPDF_FormField* pField = m_pInterForm->GetField(0, csName);
+      if (pField)
+        fields.push_back(pField);
+    }
+  }
+  return fields;
+}
+
+int CPDFSDK_InterForm::BeforeValueChange(CPDF_FormField* pField,
+                                         const CFX_WideString& csValue) {
+  int nType = pField->GetFieldType();
+  if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD)
+    return 0;
+
+  if (!OnKeyStrokeCommit(pField, csValue))
+    return -1;
+
+  if (!OnValidate(pField, csValue))
+    return -1;
+
+  return 1;
+}
+
+void CPDFSDK_InterForm::AfterValueChange(CPDF_FormField* pField) {
+#ifdef PDF_ENABLE_XFA
+  SynchronizeField(pField, FALSE);
+#endif  // PDF_ENABLE_XFA
+  int nType = pField->GetFieldType();
+  if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
+    OnCalculate(pField);
+    FX_BOOL bFormated = FALSE;
+    CFX_WideString sValue = OnFormat(pField, bFormated);
+    ResetFieldAppearance(pField, bFormated ? sValue.c_str() : nullptr, TRUE);
+    UpdateField(pField);
+  }
+}
+
+int CPDFSDK_InterForm::BeforeSelectionChange(CPDF_FormField* pField,
+                                             const CFX_WideString& csValue) {
+  if (pField->GetFieldType() != FIELDTYPE_LISTBOX)
+    return 0;
+
+  if (!OnKeyStrokeCommit(pField, csValue))
+    return -1;
+
+  if (!OnValidate(pField, csValue))
+    return -1;
+
+  return 1;
+}
+
+void CPDFSDK_InterForm::AfterSelectionChange(CPDF_FormField* pField) {
+  if (pField->GetFieldType() != FIELDTYPE_LISTBOX)
+    return;
+
+  OnCalculate(pField);
+  ResetFieldAppearance(pField, nullptr, TRUE);
+  UpdateField(pField);
+}
+
+void CPDFSDK_InterForm::AfterCheckedStatusChange(CPDF_FormField* pField) {
+  int nType = pField->GetFieldType();
+  if (nType != FIELDTYPE_CHECKBOX && nType != FIELDTYPE_RADIOBUTTON)
+    return;
+
+  OnCalculate(pField);
+  UpdateField(pField);
+}
+
+int CPDFSDK_InterForm::BeforeFormReset(CPDF_InterForm* pForm) {
+  return 0;
+}
+
+void CPDFSDK_InterForm::AfterFormReset(CPDF_InterForm* pForm) {
+  OnCalculate(nullptr);
+}
+
+int CPDFSDK_InterForm::BeforeFormImportData(CPDF_InterForm* pForm) {
+  return 0;
+}
+
+void CPDFSDK_InterForm::AfterFormImportData(CPDF_InterForm* pForm) {
+  OnCalculate(nullptr);
+}
+
+FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType) {
+  if (nFieldType < 1 || nFieldType > kNumFieldTypes)
+    return FALSE;
+  return m_bNeedHightlight[nFieldType - 1];
+}
+
+void CPDFSDK_InterForm::RemoveAllHighLight() {
+  for (int i = 0; i < kNumFieldTypes; ++i)
+    m_bNeedHightlight[i] = FALSE;
+}
+
+void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType) {
+  if (nFieldType < 0 || nFieldType > kNumFieldTypes)
+    return;
+  switch (nFieldType) {
+    case 0: {
+      for (int i = 0; i < kNumFieldTypes; ++i) {
+        m_aHighlightColor[i] = clr;
+        m_bNeedHightlight[i] = TRUE;
+      }
+      break;
+    }
+    default: {
+      m_aHighlightColor[nFieldType - 1] = clr;
+      m_bNeedHightlight[nFieldType - 1] = TRUE;
+      break;
+    }
+  }
+}
+
+FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType) {
+  if (nFieldType < 0 || nFieldType > kNumFieldTypes)
+    return FXSYS_RGB(255, 255, 255);
+  if (nFieldType == 0)
+    return m_aHighlightColor[0];
+  return m_aHighlightColor[nFieldType - 1];
+}
diff --git a/fpdfsdk/fsdk_baseform.cpp b/fpdfsdk/cpdfsdk_widget.cpp
similarity index 61%
rename from fpdfsdk/fsdk_baseform.cpp
rename to fpdfsdk/cpdfsdk_widget.cpp
index 2eda2de..3da86aa 100644
--- a/fpdfsdk/fsdk_baseform.cpp
+++ b/fpdfsdk/cpdfsdk_widget.cpp
@@ -1,58 +1,42 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2016 PDFium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "fpdfsdk/include/fsdk_baseform.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 
-#include <algorithm>
-#include <map>
 #include <memory>
-#include <vector>
 
-#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
-#include "core/fpdfapi/fpdf_parser/include/cfdf_document.h"
-#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
-#include "core/fpdfdoc/include/cpdf_actionfields.h"
+#include "core/fpdfdoc/include/cpdf_defaultappearance.h"
+#include "core/fpdfdoc/include/cpdf_formcontrol.h"
+#include "core/fpdfdoc/include/cpdf_formfield.h"
+#include "core/fpdfdoc/include/cpdf_iconfit.h"
 #include "core/fpdfdoc/include/cpdf_interform.h"
 #include "core/fxge/include/cfx_graphstatedata.h"
 #include "core/fxge/include/cfx_pathdata.h"
 #include "core/fxge/include/cfx_renderdevice.h"
-#include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/formfiller/cba_fontmap.h"
 #include "fpdfsdk/fxedit/include/fxet_edit.h"
-#include "fpdfsdk/include/cpdfsdk_annot.h"
-#include "fpdfsdk/include/fsdk_actionhandler.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
 #include "fpdfsdk/include/fsdk_define.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
-#include "fpdfsdk/include/ipdfsdk_annothandler.h"
-#include "fpdfsdk/javascript/ijs_context.h"
-#include "fpdfsdk/javascript/ijs_runtime.h"
+#include "fpdfsdk/pdfwindow/PWL_Edit.h"
 #include "fpdfsdk/pdfwindow/PWL_Utils.h"
 #include "third_party/base/stl_util.h"
 
 #ifdef PDF_ENABLE_XFA
 #include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h"
-#include "fpdfsdk/fpdfxfa/include/fpdfxfa_util.h"
 #include "xfa/fxfa/include/cxfa_eventparam.h"
+#include "xfa/fxfa/include/fxfa_widget.h"
 #include "xfa/fxfa/include/xfa_ffdocview.h"
 #include "xfa/fxfa/include/xfa_ffwidget.h"
 #include "xfa/fxfa/include/xfa_ffwidgethandler.h"
 #endif  // PDF_ENABLE_XFA
 
-PDFSDK_FieldAction::PDFSDK_FieldAction()
-    : bModifier(FALSE),
-      bShift(FALSE),
-      nCommitKey(0),
-      bKeyDown(FALSE),
-      nSelEnd(0),
-      nSelStart(0),
-      bWillCommit(FALSE),
-      bFieldFull(FALSE),
-      bRC(TRUE) {}
-
 CPDFSDK_Widget::Observer::Observer(CPDFSDK_Widget** pWatchedPtr)
     : m_pWatchedPtr(pWatchedPtr) {
   (*m_pWatchedPtr)->AddObserver(this);
@@ -144,9 +128,8 @@
   CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
   if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
     if (!m_pWidgetHandler) {
-      if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) {
+      if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView())
         m_pWidgetHandler = pDocView->GetWidgetHandler();
-      }
     }
     return m_pWidgetHandler;
   }
@@ -207,9 +190,8 @@
     case CPDF_AAction::PageInvisible:
       break;
     case CPDF_AAction::KeyStroke:
-      if (!bWillCommit) {
+      if (!bWillCommit)
         eEventType = XFA_EVENT_Change;
-      }
       break;
     case CPDF_AAction::Validate:
       eEventType = XFA_EVENT_Validate;
@@ -230,27 +212,28 @@
 }
 
 FX_BOOL CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) {
-  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
-    if (CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
-      XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
+  CXFA_FFWidget* hWidget = GetMixXFAWidget();
+  if (!hWidget)
+    return FALSE;
 
-      if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
-          GetFieldType() == FIELDTYPE_RADIOBUTTON) {
-        if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) {
-          CXFA_WidgetAcc* pAcc = hGroupWidget->GetDataAcc();
-          if (pXFAWidgetHandler->HasEvent(pAcc, eEventType))
-            return TRUE;
-        }
-      }
+  CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
+  if (!pXFAWidgetHandler)
+    return FALSE;
 
-      {
-        CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc();
-        return pXFAWidgetHandler->HasEvent(pAcc, eEventType);
-      }
+  XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
+
+  CXFA_WidgetAcc* pAcc;
+  if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
+      GetFieldType() == FIELDTYPE_RADIOBUTTON) {
+    if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) {
+      pAcc = hGroupWidget->GetDataAcc();
+      if (pXFAWidgetHandler->HasEvent(pAcc, eEventType))
+        return TRUE;
     }
   }
 
-  return FALSE;
+  pAcc = hWidget->GetDataAcc();
+  return pXFAWidgetHandler->HasEvent(pAcc, eEventType);
 }
 
 FX_BOOL CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
@@ -258,97 +241,105 @@
                                      CPDFSDK_PageView* pPageView) {
   CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
   CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
-  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
-    XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
 
-    if (eEventType != XFA_EVENT_Unknown) {
-      if (CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
-        CXFA_EventParam param;
-        param.m_eType = eEventType;
-        param.m_wsChange = data.sChange;
-        param.m_iCommitKey = data.nCommitKey;
-        param.m_bShift = data.bShift;
-        param.m_iSelStart = data.nSelStart;
-        param.m_iSelEnd = data.nSelEnd;
-        param.m_wsFullText = data.sValue;
-        param.m_bKeyDown = data.bKeyDown;
-        param.m_bModifier = data.bModifier;
-        param.m_wsNewText = data.sValue;
-        if (data.nSelEnd > data.nSelStart)
-          param.m_wsNewText.Delete(data.nSelStart,
-                                   data.nSelEnd - data.nSelStart);
-        for (int i = 0; i < data.sChange.GetLength(); i++)
-          param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
-        param.m_wsPrevText = data.sValue;
+  CXFA_FFWidget* hWidget = GetMixXFAWidget();
+  if (!hWidget)
+    return FALSE;
 
-        if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
-            GetFieldType() == FIELDTYPE_RADIOBUTTON) {
-          if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) {
-            CXFA_WidgetAcc* pAcc = hGroupWidget->GetDataAcc();
-            param.m_pTarget = pAcc;
-            if (pXFAWidgetHandler->ProcessEvent(pAcc, &param) !=
-                XFA_EVENTERROR_Success) {
-              return FALSE;
-            }
-          }
-        }
-        CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc();
-        param.m_pTarget = pAcc;
-        int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
+  XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
+  if (eEventType == XFA_EVENT_Unknown)
+    return FALSE;
 
-        if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) {
-          pDocView->UpdateDocView();
-        }
-        return nRet == XFA_EVENTERROR_Success;
+  CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
+  if (!pXFAWidgetHandler)
+    return FALSE;
+
+  CXFA_EventParam param;
+  param.m_eType = eEventType;
+  param.m_wsChange = data.sChange;
+  param.m_iCommitKey = data.nCommitKey;
+  param.m_bShift = data.bShift;
+  param.m_iSelStart = data.nSelStart;
+  param.m_iSelEnd = data.nSelEnd;
+  param.m_wsFullText = data.sValue;
+  param.m_bKeyDown = data.bKeyDown;
+  param.m_bModifier = data.bModifier;
+  param.m_wsNewText = data.sValue;
+  if (data.nSelEnd > data.nSelStart)
+    param.m_wsNewText.Delete(data.nSelStart, data.nSelEnd - data.nSelStart);
+
+  for (int i = 0; i < data.sChange.GetLength(); i++)
+    param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
+  param.m_wsPrevText = data.sValue;
+
+  if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
+      GetFieldType() == FIELDTYPE_RADIOBUTTON) {
+    if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) {
+      CXFA_WidgetAcc* pAcc = hGroupWidget->GetDataAcc();
+      param.m_pTarget = pAcc;
+      if (pXFAWidgetHandler->ProcessEvent(pAcc, &param) !=
+          XFA_EVENTERROR_Success) {
+        return FALSE;
       }
     }
   }
+  CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc();
+  param.m_pTarget = pAcc;
+  int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
 
-  return FALSE;
+  if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView())
+    pDocView->UpdateDocView();
+
+  return nRet == XFA_EVENTERROR_Success;
 }
 
 void CPDFSDK_Widget::Synchronize(FX_BOOL bSynchronizeElse) {
-  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
-    CPDF_FormField* pFormField = GetFormField();
-    if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
-      switch (GetFieldType()) {
-        case FIELDTYPE_CHECKBOX:
-        case FIELDTYPE_RADIOBUTTON: {
-          CPDF_FormControl* pFormCtrl = GetFormControl();
-          XFA_CHECKSTATE eCheckState =
-              pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off;
-          pWidgetAcc->SetCheckState(eCheckState, true);
-        } break;
-        case FIELDTYPE_TEXTFIELD:
-          pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
-          break;
-        case FIELDTYPE_LISTBOX: {
-          pWidgetAcc->ClearAllSelections();
+  CXFA_FFWidget* hWidget = GetMixXFAWidget();
+  if (!hWidget)
+    return;
 
-          for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
-            int nIndex = pFormField->GetSelectedIndex(i);
-            if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
-              pWidgetAcc->SetItemState(nIndex, TRUE, false, FALSE, TRUE);
-          }
-        } break;
-        case FIELDTYPE_COMBOBOX: {
-          pWidgetAcc->ClearAllSelections();
+  CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
+  if (!pWidgetAcc)
+    return;
 
-          for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
-            int nIndex = pFormField->GetSelectedIndex(i);
-            if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
-              pWidgetAcc->SetItemState(nIndex, TRUE, false, FALSE, TRUE);
-          }
-        }
+  CPDF_FormField* pFormField = GetFormField();
+  switch (GetFieldType()) {
+    case FIELDTYPE_CHECKBOX:
+    case FIELDTYPE_RADIOBUTTON: {
+      CPDF_FormControl* pFormCtrl = GetFormControl();
+      XFA_CHECKSTATE eCheckState =
+          pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off;
+      pWidgetAcc->SetCheckState(eCheckState, true);
+      break;
+    }
+    case FIELDTYPE_TEXTFIELD:
+      pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
+      break;
+    case FIELDTYPE_LISTBOX: {
+      pWidgetAcc->ClearAllSelections();
 
-          pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
-          break;
+      for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
+        int nIndex = pFormField->GetSelectedIndex(i);
+        if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
+          pWidgetAcc->SetItemState(nIndex, TRUE, false, FALSE, TRUE);
       }
+      break;
+    }
+    case FIELDTYPE_COMBOBOX: {
+      pWidgetAcc->ClearAllSelections();
 
-      if (bSynchronizeElse)
-        pWidgetAcc->ProcessValueChanged();
+      for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
+        int nIndex = pFormField->GetSelectedIndex(i);
+        if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
+          pWidgetAcc->SetItemState(nIndex, TRUE, false, FALSE, TRUE);
+      }
+      pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
+      break;
     }
   }
+
+  if (bSynchronizeElse)
+    pWidgetAcc->ProcessValueChanged();
 }
 
 void CPDFSDK_Widget::SynchronizeXFAValue() {
@@ -393,7 +384,8 @@
             pFormField->GetControlIndex(pFormControl),
             pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true);
       }
-    } break;
+      break;
+    }
     case FIELDTYPE_RADIOBUTTON: {
       // TODO(weili): Check whether we need to handle checkbox and radio
       // button differently, otherwise, merge these two cases.
@@ -402,14 +394,16 @@
             pFormField->GetControlIndex(pFormControl),
             pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true);
       }
-    } break;
+      break;
+    }
     case FIELDTYPE_TEXTFIELD: {
       if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
         CFX_WideString sValue;
         pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
         pFormField->SetValue(sValue, TRUE);
       }
-    } break;
+      break;
+    }
     case FIELDTYPE_LISTBOX: {
       pFormField->ClearSelection(FALSE);
 
@@ -422,7 +416,8 @@
           }
         }
       }
-    } break;
+      break;
+    }
     case FIELDTYPE_COMBOBOX: {
       pFormField->ClearSelection(FALSE);
 
@@ -439,7 +434,8 @@
         pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
         pFormField->SetValue(sValue, TRUE);
       }
-    } break;
+      break;
+    }
   }
 }
 
@@ -462,7 +458,8 @@
           pFormField->InsertOption(swText, i, TRUE);
         }
       }
-    } break;
+      break;
+    }
     case FIELDTYPE_COMBOBOX: {
       pFormField->ClearSelection(FALSE);
       pFormField->ClearOptions(FALSE);
@@ -477,7 +474,8 @@
       }
 
       pFormField->SetValue(L"", TRUE);
-    } break;
+      break;
+    }
   }
 }
 #endif  // PDF_ENABLE_XFA
@@ -602,16 +600,15 @@
 FX_BOOL CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const {
   CPDF_FormControl* pFormCtrl = GetFormControl();
   CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
-  if (da.HasColor()) {
-    FX_ARGB argb;
-    int iColorType = COLORTYPE_TRANSPARENT;
-    da.GetColor(argb, iColorType);
-    color = FX_ARGBTOCOLORREF(argb);
+  if (!da.HasColor())
+    return FALSE;
 
-    return iColorType != COLORTYPE_TRANSPARENT;
-  }
+  FX_ARGB argb;
+  int iColorType = COLORTYPE_TRANSPARENT;
+  da.GetColor(argb, iColorType);
+  color = FX_ARGBTOCOLORREF(argb);
 
-  return FALSE;
+  return iColorType != COLORTYPE_TRANSPARENT;
 }
 
 FX_FLOAT CPDFSDK_Widget::GetFontSize() const {
@@ -775,7 +772,8 @@
       FX_BOOL bFormated = FALSE;
       CFX_WideString sValue = OnFormat(bFormated);
       ResetAppearance(bFormated ? sValue.c_str() : nullptr, TRUE);
-    } break;
+      break;
+    }
     default:
       ResetAppearance(nullptr, FALSE);
       break;
@@ -867,30 +865,31 @@
 void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice,
                                 CPDFSDK_PageView* pPageView) {
   int nFieldType = GetFieldType();
-  if (m_pInterForm->IsNeedHighLight(nFieldType)) {
-    CFX_FloatRect rc = GetRect();
-    FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType);
-    uint8_t alpha = m_pInterForm->GetHighlightAlpha();
+  if (!m_pInterForm->IsNeedHighLight(nFieldType))
+    return;
 
-    CFX_FloatRect rcDevice;
-    ASSERT(m_pInterForm->GetDocument());
-    CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv();
-    if (!pEnv)
-      return;
-    CFX_Matrix page2device;
-    pPageView->GetCurrentMatrix(page2device);
-    page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom),
-                          rcDevice.left, rcDevice.bottom);
-    page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top),
-                          rcDevice.right, rcDevice.top);
+  CFX_FloatRect rc = GetRect();
+  FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType);
+  uint8_t alpha = m_pInterForm->GetHighlightAlpha();
 
-    rcDevice.Normalize();
+  CFX_FloatRect rcDevice;
+  ASSERT(m_pInterForm->GetDocument());
+  CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv();
+  if (!pEnv)
+    return;
+  CFX_Matrix page2device;
+  pPageView->GetCurrentMatrix(page2device);
+  page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom),
+                        rcDevice.left, rcDevice.bottom);
+  page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top),
+                        rcDevice.right, rcDevice.top);
 
-    FX_ARGB argb = ArgbEncode((int)alpha, color);
-    FX_RECT rcDev((int)rcDevice.left, (int)rcDevice.top, (int)rcDevice.right,
-                  (int)rcDevice.bottom);
-    pDevice->FillRect(&rcDev, argb);
-  }
+  rcDevice.Normalize();
+
+  FX_ARGB argb = ArgbEncode((int)alpha, color);
+  FX_RECT rcDev((int)rcDevice.left, (int)rcDevice.top, (int)rcDevice.right,
+                (int)rcDevice.bottom);
+  pDevice->FillRect(&rcDev, argb);
 }
 
 void CPDFSDK_Widget::ResetAppearance_PushButton() {
@@ -976,29 +975,27 @@
   CFX_WideString csWCaption;
   CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption;
 
-  if (pControl->HasMKEntry("CA")) {
+  if (pControl->HasMKEntry("CA"))
     csNormalCaption = pControl->GetNormalCaption();
-  }
-  if (pControl->HasMKEntry("RC")) {
+
+  if (pControl->HasMKEntry("RC"))
     csRolloverCaption = pControl->GetRolloverCaption();
-  }
-  if (pControl->HasMKEntry("AC")) {
+
+  if (pControl->HasMKEntry("AC"))
     csDownCaption = pControl->GetDownCaption();
-  }
 
   CPDF_Stream* pNormalIcon = nullptr;
   CPDF_Stream* pRolloverIcon = nullptr;
   CPDF_Stream* pDownIcon = nullptr;
 
-  if (pControl->HasMKEntry("I")) {
+  if (pControl->HasMKEntry("I"))
     pNormalIcon = pControl->GetNormalIcon();
-  }
-  if (pControl->HasMKEntry("RI")) {
+
+  if (pControl->HasMKEntry("RI"))
     pRolloverIcon = pControl->GetRolloverIcon();
-  }
-  if (pControl->HasMKEntry("IX")) {
+
+  if (pControl->HasMKEntry("IX"))
     pDownIcon = pControl->GetDownIcon();
-  }
 
   if (pNormalIcon) {
     if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
@@ -1737,9 +1734,9 @@
 
 CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const {
   CPWL_Color crBackground = GetFillPWLColor();
-  if (crBackground.nColorType != COLORTYPE_TRANSPARENT) {
+  if (crBackground.nColorType != COLORTYPE_TRANSPARENT)
     return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
-  }
+
   return "";
 }
 
@@ -1912,9 +1909,8 @@
         param.m_pTarget = pAcc;
         int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
 
-        if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) {
+        if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView())
           pDocView->UpdateDocView();
-        }
 
         if (nRet == XFA_EVENTERROR_Success)
           return TRUE;
@@ -1979,895 +1975,14 @@
   CPDF_Annot* pAnnot = GetPDFAnnot();
   CFX_FloatRect annotRect;
   pAnnot->GetRect(annotRect);
-  if (annotRect.Contains(pageX, pageY)) {
-    if (!IsVisible())
-      return FALSE;
-
-    int nFieldFlags = GetFieldFlags();
-    if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
-      return FALSE;
-
-    return TRUE;
-  }
-  return FALSE;
-}
-
-#ifdef PDF_ENABLE_XFA
-CPDFSDK_XFAWidget::CPDFSDK_XFAWidget(CXFA_FFWidget* pAnnot,
-                                     CPDFSDK_PageView* pPageView,
-                                     CPDFSDK_InterForm* pInterForm)
-    : CPDFSDK_Annot(pPageView),
-      m_pInterForm(pInterForm),
-      m_hXFAWidget(pAnnot) {}
-
-FX_BOOL CPDFSDK_XFAWidget::IsXFAField() {
-  return TRUE;
-}
-
-CXFA_FFWidget* CPDFSDK_XFAWidget::GetXFAWidget() const {
-  return m_hXFAWidget;
-}
-
-CFX_ByteString CPDFSDK_XFAWidget::GetType() const {
-  return FSDK_XFAWIDGET_TYPENAME;
-}
-
-CFX_ByteString CPDFSDK_XFAWidget::GetSubType() const {
-  return "";
-}
-
-CFX_FloatRect CPDFSDK_XFAWidget::GetRect() const {
-  CFX_RectF rcBBox;
-  GetXFAWidget()->GetRect(rcBBox);
-  return CFX_FloatRect(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
-                       rcBBox.top + rcBBox.height);
-}
-#endif  // PDF_ENABLE_XFA
-
-CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument)
-    : m_pDocument(pDocument),
-      m_pInterForm(new CPDF_InterForm(m_pDocument->GetPDFDocument())),
-#ifdef PDF_ENABLE_XFA
-      m_bXfaCalculate(TRUE),
-      m_bXfaValidationsEnabled(TRUE),
-#endif  // PDF_ENABLE_XFA
-      m_bCalculate(TRUE),
-      m_bBusy(FALSE) {
-  m_pInterForm->SetFormNotify(this);
-  for (int i = 0; i < kNumFieldTypes; ++i)
-    m_bNeedHightlight[i] = FALSE;
-  m_iHighlightAlpha = 0;
-}
-
-CPDFSDK_InterForm::~CPDFSDK_InterForm() {
-  m_Map.clear();
-#ifdef PDF_ENABLE_XFA
-  m_XFAMap.clear();
-#endif  // PDF_ENABLE_XFA
-}
-
-FX_BOOL CPDFSDK_InterForm::HighlightWidgets() {
-  return FALSE;
-}
-
-CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget,
-                                              FX_BOOL bNext) const {
-  std::unique_ptr<CBA_AnnotIterator> pIterator(
-      new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", ""));
-
-  if (bNext) {
-    return (CPDFSDK_Widget*)pIterator->GetNextAnnot(pWidget);
-  }
-  return (CPDFSDK_Widget*)pIterator->GetPrevAnnot(pWidget);
-}
-
-CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl,
-                                             bool createIfNeeded) const {
-  if (!pControl || !m_pInterForm)
-    return nullptr;
-
-  CPDFSDK_Widget* pWidget = nullptr;
-  const auto it = m_Map.find(pControl);
-  if (it != m_Map.end())
-    pWidget = it->second;
-  if (pWidget)
-    return pWidget;
-  if (!createIfNeeded)
-    return nullptr;
-
-  CPDF_Dictionary* pControlDict = pControl->GetWidget();
-  CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
-  CPDFSDK_PageView* pPage = nullptr;
-
-  if (CPDF_Dictionary* pPageDict = pControlDict->GetDictBy("P")) {
-    int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
-    if (nPageIndex >= 0) {
-      pPage = m_pDocument->GetPageView(nPageIndex);
-    }
-  }
-
-  if (!pPage) {
-    int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
-    if (nPageIndex >= 0) {
-      pPage = m_pDocument->GetPageView(nPageIndex);
-    }
-  }
-
-  if (!pPage)
-    return nullptr;
-
-  return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict);
-}
-
-void CPDFSDK_InterForm::GetWidgets(
-    const CFX_WideString& sFieldName,
-    std::vector<CPDFSDK_Widget*>* widgets) const {
-  for (int i = 0, sz = m_pInterForm->CountFields(sFieldName); i < sz; ++i) {
-    CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName);
-    ASSERT(pFormField);
-    GetWidgets(pFormField, widgets);
-  }
-}
-
-void CPDFSDK_InterForm::GetWidgets(
-    CPDF_FormField* pField,
-    std::vector<CPDFSDK_Widget*>* widgets) const {
-  for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
-    CPDF_FormControl* pFormCtrl = pField->GetControl(i);
-    ASSERT(pFormCtrl);
-    CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, true);
-    if (pWidget)
-      widgets->push_back(pWidget);
-  }
-}
-
-int CPDFSDK_InterForm::GetPageIndexByAnnotDict(
-    CPDF_Document* pDocument,
-    CPDF_Dictionary* pAnnotDict) const {
-  ASSERT(pAnnotDict);
-
-  for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) {
-    if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i)) {
-      if (CPDF_Array* pAnnots = pPageDict->GetArrayBy("Annots")) {
-        for (int j = 0, jsz = pAnnots->GetCount(); j < jsz; j++) {
-          CPDF_Object* pDict = pAnnots->GetDirectObjectAt(j);
-          if (pAnnotDict == pDict) {
-            return i;
-          }
-        }
-      }
-    }
-  }
-
-  return -1;
-}
-
-void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl,
-                               CPDFSDK_Widget* pWidget) {
-  m_Map[pControl] = pWidget;
-}
-
-void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl) {
-  m_Map.erase(pControl);
-}
-
-void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled) {
-  m_bCalculate = bEnabled;
-}
-
-FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const {
-  return m_bCalculate;
-}
-
-#ifdef PDF_ENABLE_XFA
-void CPDFSDK_InterForm::AddXFAMap(CXFA_FFWidget* hWidget,
-                                  CPDFSDK_XFAWidget* pWidget) {
-  ASSERT(hWidget);
-  m_XFAMap[hWidget] = pWidget;
-}
-
-void CPDFSDK_InterForm::RemoveXFAMap(CXFA_FFWidget* hWidget) {
-  ASSERT(hWidget);
-  m_XFAMap.erase(hWidget);
-}
-
-CPDFSDK_XFAWidget* CPDFSDK_InterForm::GetXFAWidget(CXFA_FFWidget* hWidget) {
-  ASSERT(hWidget);
-  auto it = m_XFAMap.find(hWidget);
-  return it != m_XFAMap.end() ? it->second : nullptr;
-}
-
-void CPDFSDK_InterForm::XfaEnableCalculate(FX_BOOL bEnabled) {
-  m_bXfaCalculate = bEnabled;
-}
-FX_BOOL CPDFSDK_InterForm::IsXfaCalculateEnabled() const {
-  return m_bXfaCalculate;
-}
-
-FX_BOOL CPDFSDK_InterForm::IsXfaValidationsEnabled() {
-  return m_bXfaValidationsEnabled;
-}
-void CPDFSDK_InterForm::XfaSetValidationsEnabled(FX_BOOL bEnabled) {
-  m_bXfaValidationsEnabled = bEnabled;
-}
-#endif  // PDF_ENABLE_XFA
-
-void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) {
-  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
-  ASSERT(pEnv);
-  if (!pEnv->IsJSInitiated())
-    return;
-
-  if (m_bBusy)
-    return;
-
-  m_bBusy = TRUE;
-
-  if (IsCalculateEnabled()) {
-    IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
-    pRuntime->SetReaderDocument(m_pDocument);
-
-    int nSize = m_pInterForm->CountFieldsInCalculationOrder();
-    for (int i = 0; i < nSize; i++) {
-      if (CPDF_FormField* pField =
-              m_pInterForm->GetFieldInCalculationOrder(i)) {
-        int nType = pField->GetFieldType();
-        if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
-          CPDF_AAction aAction = pField->GetAdditionalAction();
-          if (aAction.GetDict() &&
-              aAction.ActionExist(CPDF_AAction::Calculate)) {
-            CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate);
-            if (action.GetDict()) {
-              CFX_WideString csJS = action.GetJavaScript();
-              if (!csJS.IsEmpty()) {
-                IJS_Context* pContext = pRuntime->NewContext();
-                CFX_WideString sOldValue = pField->GetValue();
-                CFX_WideString sValue = sOldValue;
-                FX_BOOL bRC = TRUE;
-                pContext->OnField_Calculate(pFormField, pField, sValue, bRC);
-
-                CFX_WideString sInfo;
-                FX_BOOL bRet = pContext->RunScript(csJS, &sInfo);
-                pRuntime->ReleaseContext(pContext);
-
-                if (bRet) {
-                  if (bRC) {
-                    if (sValue.Compare(sOldValue) != 0)
-                      pField->SetValue(sValue, TRUE);
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-
-  m_bBusy = FALSE;
-}
-
-CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField,
-                                           FX_BOOL& bFormated) {
-  CFX_WideString sValue = pFormField->GetValue();
-  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
-  ASSERT(pEnv);
-  if (!pEnv->IsJSInitiated()) {
-    bFormated = FALSE;
-    return sValue;
-  }
-
-  IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
-  pRuntime->SetReaderDocument(m_pDocument);
-
-  if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX) {
-    if (pFormField->CountSelectedItems() > 0) {
-      int index = pFormField->GetSelectedIndex(0);
-      if (index >= 0)
-        sValue = pFormField->GetOptionLabel(index);
-    }
-  }
-
-  bFormated = FALSE;
-
-  CPDF_AAction aAction = pFormField->GetAdditionalAction();
-  if (aAction.GetDict() && aAction.ActionExist(CPDF_AAction::Format)) {
-    CPDF_Action action = aAction.GetAction(CPDF_AAction::Format);
-    if (action.GetDict()) {
-      CFX_WideString script = action.GetJavaScript();
-      if (!script.IsEmpty()) {
-        CFX_WideString Value = sValue;
-
-        IJS_Context* pContext = pRuntime->NewContext();
-        pContext->OnField_Format(pFormField, Value, TRUE);
-        CFX_WideString sInfo;
-        FX_BOOL bRet = pContext->RunScript(script, &sInfo);
-        pRuntime->ReleaseContext(pContext);
-
-        if (bRet) {
-          sValue = Value;
-          bFormated = TRUE;
-        }
-      }
-    }
-  }
-
-  return sValue;
-}
-
-void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField,
-                                             const FX_WCHAR* sValue,
-                                             FX_BOOL bValueChanged) {
-  for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
-    CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
-    ASSERT(pFormCtrl);
-    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false))
-      pWidget->ResetAppearance(sValue, bValueChanged);
-  }
-}
-
-void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) {
-  for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
-    CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
-    ASSERT(pFormCtrl);
-
-    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) {
-      CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
-      CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller();
-      UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
-      CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage, false);
-      FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget);
-
-      pEnv->FFI_Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right,
-                           rcBBox.bottom);
-    }
-  }
-}
-
-FX_BOOL CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField,
-                                             const CFX_WideString& csValue) {
-  CPDF_AAction aAction = pFormField->GetAdditionalAction();
-  if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::KeyStroke))
-    return TRUE;
-
-  CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke);
-  if (!action.GetDict())
-    return TRUE;
-
-  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
-  CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
-  PDFSDK_FieldAction fa;
-  fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
-  fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
-  fa.sValue = csValue;
-  pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke,
-                                           m_pDocument, pFormField, fa);
-  return fa.bRC;
-}
-
-FX_BOOL CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField,
-                                      const CFX_WideString& csValue) {
-  CPDF_AAction aAction = pFormField->GetAdditionalAction();
-  if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::Validate))
-    return TRUE;
-
-  CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate);
-  if (!action.GetDict())
-    return TRUE;
-
-  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
-  CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
-  PDFSDK_FieldAction fa;
-  fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
-  fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
-  fa.sValue = csValue;
-  pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate,
-                                           m_pDocument, pFormField, fa);
-  return fa.bRC;
-}
-
-FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action) {
-  ASSERT(action.GetDict());
-
-  CPDF_ActionFields af(&action);
-  std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
-  std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
-
-  bool bHide = action.GetHideStatus();
-  FX_BOOL bChanged = FALSE;
-
-  for (CPDF_FormField* pField : fields) {
-    for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
-      CPDF_FormControl* pControl = pField->GetControl(i);
-      ASSERT(pControl);
-
-      if (CPDFSDK_Widget* pWidget = GetWidget(pControl, false)) {
-        uint32_t nFlags = pWidget->GetFlags();
-        nFlags &= ~ANNOTFLAG_INVISIBLE;
-        nFlags &= ~ANNOTFLAG_NOVIEW;
-        if (bHide)
-          nFlags |= ANNOTFLAG_HIDDEN;
-        else
-          nFlags &= ~ANNOTFLAG_HIDDEN;
-        pWidget->SetFlags(nFlags);
-        pWidget->GetPageView()->UpdateView(pWidget);
-        bChanged = TRUE;
-      }
-    }
-  }
-
-  return bChanged;
-}
-
-FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action) {
-  CFX_WideString sDestination = action.GetFilePath();
-  if (sDestination.IsEmpty())
+  if (!annotRect.Contains(pageX, pageY))
     return FALSE;
 
-  CPDF_Dictionary* pActionDict = action.GetDict();
-  if (pActionDict->KeyExist("Fields")) {
-    CPDF_ActionFields af(&action);
-    uint32_t dwFlags = action.GetFlags();
-    std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
-    std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
-    if (!fields.empty()) {
-      bool bIncludeOrExclude = !(dwFlags & 0x01);
-      if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude))
-        return FALSE;
-
-      return SubmitFields(sDestination, fields, bIncludeOrExclude, false);
-    }
-  }
-  if (m_pInterForm->CheckRequiredFields(nullptr, true))
+  if (!IsVisible())
     return FALSE;
 
-  return SubmitForm(sDestination, FALSE);
-}
-
-FX_BOOL CPDFSDK_InterForm::SubmitFields(
-    const CFX_WideString& csDestination,
-    const std::vector<CPDF_FormField*>& fields,
-    bool bIncludeOrExclude,
-    bool bUrlEncoded) {
-  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
-
-  CFX_ByteTextBuf textBuf;
-  ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf);
-
-  uint8_t* pBuffer = textBuf.GetBuffer();
-  FX_STRSIZE nBufSize = textBuf.GetLength();
-
-  if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize))
+  if ((GetFieldFlags() & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
     return FALSE;
 
-  pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str());
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile,
-                                               CFX_WideString csTxtFile) {
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf,
-                                               FX_STRSIZE& nBufSize) {
-  CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize);
-  if (pFDF) {
-    CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDictBy("FDF");
-    if (!pMainDict)
-      return FALSE;
-
-    // Get fields
-    CPDF_Array* pFields = pMainDict->GetArrayBy("Fields");
-    if (!pFields)
-      return FALSE;
-
-    CFX_ByteTextBuf fdfEncodedData;
-    for (uint32_t i = 0; i < pFields->GetCount(); i++) {
-      CPDF_Dictionary* pField = pFields->GetDictAt(i);
-      if (!pField)
-        continue;
-      CFX_WideString name;
-      name = pField->GetUnicodeTextBy("T");
-      CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
-      CFX_ByteString csBValue = pField->GetStringBy("V");
-      CFX_WideString csWValue = PDF_DecodeText(csBValue);
-      CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue);
-
-      fdfEncodedData << name_b.GetBuffer(name_b.GetLength());
-      name_b.ReleaseBuffer();
-      fdfEncodedData << "=";
-      fdfEncodedData << csValue_b.GetBuffer(csValue_b.GetLength());
-      csValue_b.ReleaseBuffer();
-      if (i != pFields->GetCount() - 1)
-        fdfEncodedData << "&";
-    }
-
-    nBufSize = fdfEncodedData.GetLength();
-    pBuf = FX_Alloc(uint8_t, nBufSize);
-    FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize);
-  }
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf(
-    const std::vector<CPDF_FormField*>& fields,
-    bool bIncludeOrExclude,
-    CFX_ByteTextBuf& textBuf) {
-  std::unique_ptr<CFDF_Document> pFDF(m_pInterForm->ExportToFDF(
-      m_pDocument->GetPath().AsStringC(), fields, bIncludeOrExclude));
-  return pFDF ? pFDF->WriteBuf(textBuf) : FALSE;
-}
-
-#ifdef PDF_ENABLE_XFA
-void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField,
-                                         FX_BOOL bSynchronizeElse) {
-  for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
-    CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
-    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) {
-      pWidget->Synchronize(bSynchronizeElse);
-    }
-  }
-}
-#endif  // PDF_ENABLE_XFA
-
-CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(
-    const CFX_WideString& sFileExt) {
-  CFX_WideString sFileName;
-  return L"";
-}
-
-FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination,
-                                      FX_BOOL bUrlEncoded) {
-  if (sDestination.IsEmpty())
-    return FALSE;
-
-  if (!m_pDocument || !m_pInterForm)
-    return FALSE;
-
-  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
-  CFX_WideString wsPDFFilePath = m_pDocument->GetPath();
-  CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath.AsStringC());
-  if (!pFDFDoc)
-    return FALSE;
-
-  CFX_ByteTextBuf FdfBuffer;
-  FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer);
-  delete pFDFDoc;
-  if (!bRet)
-    return FALSE;
-
-  uint8_t* pBuffer = FdfBuffer.GetBuffer();
-  FX_STRSIZE nBufSize = FdfBuffer.GetLength();
-
-  if (bUrlEncoded) {
-    if (!FDFToURLEncodedData(pBuffer, nBufSize))
-      return FALSE;
-  }
-
-  pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str());
-
-  if (bUrlEncoded)
-    FX_Free(pBuffer);
-
   return TRUE;
 }
-
-FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) {
-  CFDF_Document* pFDF =
-      m_pInterForm->ExportToFDF(m_pDocument->GetPath().AsStringC());
-  if (!pFDF)
-    return FALSE;
-
-  FX_BOOL bRet = pFDF->WriteBuf(textBuf);
-  delete pFDF;
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action) {
-  ASSERT(action.GetDict());
-
-  CPDF_Dictionary* pActionDict = action.GetDict();
-  if (!pActionDict->KeyExist("Fields"))
-    return m_pInterForm->ResetForm(true);
-
-  CPDF_ActionFields af(&action);
-  uint32_t dwFlags = action.GetFlags();
-
-  std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
-  std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
-  return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), true);
-}
-
-FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action) {
-  return FALSE;
-}
-
-std::vector<CPDF_FormField*> CPDFSDK_InterForm::GetFieldFromObjects(
-    const std::vector<CPDF_Object*>& objects) const {
-  std::vector<CPDF_FormField*> fields;
-  for (CPDF_Object* pObject : objects) {
-    if (pObject && pObject->IsString()) {
-      CFX_WideString csName = pObject->GetUnicodeText();
-      CPDF_FormField* pField = m_pInterForm->GetField(0, csName);
-      if (pField)
-        fields.push_back(pField);
-    }
-  }
-  return fields;
-}
-
-int CPDFSDK_InterForm::BeforeValueChange(CPDF_FormField* pField,
-                                         const CFX_WideString& csValue) {
-  int nType = pField->GetFieldType();
-  if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD)
-    return 0;
-
-  if (!OnKeyStrokeCommit(pField, csValue))
-    return -1;
-
-  if (!OnValidate(pField, csValue))
-    return -1;
-
-  return 1;
-}
-
-void CPDFSDK_InterForm::AfterValueChange(CPDF_FormField* pField) {
-#ifdef PDF_ENABLE_XFA
-  SynchronizeField(pField, FALSE);
-#endif  // PDF_ENABLE_XFA
-  int nType = pField->GetFieldType();
-  if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
-    OnCalculate(pField);
-    FX_BOOL bFormated = FALSE;
-    CFX_WideString sValue = OnFormat(pField, bFormated);
-    ResetFieldAppearance(pField, bFormated ? sValue.c_str() : nullptr, TRUE);
-    UpdateField(pField);
-  }
-}
-
-int CPDFSDK_InterForm::BeforeSelectionChange(CPDF_FormField* pField,
-                                             const CFX_WideString& csValue) {
-  if (pField->GetFieldType() != FIELDTYPE_LISTBOX)
-    return 0;
-
-  if (!OnKeyStrokeCommit(pField, csValue))
-    return -1;
-
-  if (!OnValidate(pField, csValue))
-    return -1;
-
-  return 1;
-}
-
-void CPDFSDK_InterForm::AfterSelectionChange(CPDF_FormField* pField) {
-  if (pField->GetFieldType() == FIELDTYPE_LISTBOX) {
-    OnCalculate(pField);
-    ResetFieldAppearance(pField, nullptr, TRUE);
-    UpdateField(pField);
-  }
-}
-
-void CPDFSDK_InterForm::AfterCheckedStatusChange(CPDF_FormField* pField) {
-  int nType = pField->GetFieldType();
-  if (nType == FIELDTYPE_CHECKBOX || nType == FIELDTYPE_RADIOBUTTON) {
-    OnCalculate(pField);
-    UpdateField(pField);
-  }
-}
-
-int CPDFSDK_InterForm::BeforeFormReset(CPDF_InterForm* pForm) {
-  return 0;
-}
-
-void CPDFSDK_InterForm::AfterFormReset(CPDF_InterForm* pForm) {
-  OnCalculate(nullptr);
-}
-
-int CPDFSDK_InterForm::BeforeFormImportData(CPDF_InterForm* pForm) {
-  return 0;
-}
-
-void CPDFSDK_InterForm::AfterFormImportData(CPDF_InterForm* pForm) {
-  OnCalculate(nullptr);
-}
-
-FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType) {
-  if (nFieldType < 1 || nFieldType > kNumFieldTypes)
-    return FALSE;
-  return m_bNeedHightlight[nFieldType - 1];
-}
-
-void CPDFSDK_InterForm::RemoveAllHighLight() {
-  for (int i = 0; i < kNumFieldTypes; ++i)
-    m_bNeedHightlight[i] = FALSE;
-}
-
-void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType) {
-  if (nFieldType < 0 || nFieldType > kNumFieldTypes)
-    return;
-  switch (nFieldType) {
-    case 0: {
-      for (int i = 0; i < kNumFieldTypes; ++i) {
-        m_aHighlightColor[i] = clr;
-        m_bNeedHightlight[i] = TRUE;
-      }
-      break;
-    }
-    default: {
-      m_aHighlightColor[nFieldType - 1] = clr;
-      m_bNeedHightlight[nFieldType - 1] = TRUE;
-      break;
-    }
-  }
-}
-
-FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType) {
-  if (nFieldType < 0 || nFieldType > kNumFieldTypes)
-    return FXSYS_RGB(255, 255, 255);
-  if (nFieldType == 0)
-    return m_aHighlightColor[0];
-  return m_aHighlightColor[nFieldType - 1];
-}
-
-CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView,
-                                     const CFX_ByteString& sType,
-                                     const CFX_ByteString& sSubType)
-    : m_eTabOrder(STRUCTURE),
-      m_pPageView(pPageView),
-      m_sType(sType),
-      m_sSubType(sSubType) {
-  CPDF_Page* pPDFPage = m_pPageView->GetPDFPage();
-  CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetStringBy("Tabs");
-  if (sTabs == "R")
-    m_eTabOrder = ROW;
-  else if (sTabs == "C")
-    m_eTabOrder = COLUMN;
-
-  GenerateResults();
-}
-
-CBA_AnnotIterator::~CBA_AnnotIterator() {}
-
-CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() {
-  return m_Annots.empty() ? nullptr : m_Annots.front();
-}
-
-CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() {
-  return m_Annots.empty() ? nullptr : m_Annots.back();
-}
-
-CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) {
-  auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot);
-  if (iter == m_Annots.end())
-    return nullptr;
-  ++iter;
-  if (iter == m_Annots.end())
-    iter = m_Annots.begin();
-  return *iter;
-}
-
-CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) {
-  auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot);
-  if (iter == m_Annots.end())
-    return nullptr;
-  if (iter == m_Annots.begin())
-    iter = m_Annots.end();
-  return *(--iter);
-}
-
-// static
-bool CBA_AnnotIterator::CompareByLeftAscending(const CPDFSDK_Annot* p1,
-                                               const CPDFSDK_Annot* p2) {
-  return GetAnnotRect(p1).left < GetAnnotRect(p2).left;
-}
-
-// static
-bool CBA_AnnotIterator::CompareByTopDescending(const CPDFSDK_Annot* p1,
-                                               const CPDFSDK_Annot* p2) {
-  return GetAnnotRect(p1).top > GetAnnotRect(p2).top;
-}
-
-void CBA_AnnotIterator::GenerateResults() {
-  switch (m_eTabOrder) {
-    case STRUCTURE: {
-      for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
-        CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
-        if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
-          m_Annots.push_back(pAnnot);
-      }
-    } break;
-    case ROW: {
-      std::vector<CPDFSDK_Annot*> sa;
-      for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
-        CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
-        if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
-          sa.push_back(pAnnot);
-      }
-
-      std::sort(sa.begin(), sa.end(), CompareByLeftAscending);
-      while (!sa.empty()) {
-        int nLeftTopIndex = -1;
-        FX_FLOAT fTop = 0.0f;
-        for (int i = sa.size() - 1; i >= 0; i--) {
-          CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
-          if (rcAnnot.top > fTop) {
-            nLeftTopIndex = i;
-            fTop = rcAnnot.top;
-          }
-        }
-        if (nLeftTopIndex >= 0) {
-          CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex];
-          CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
-          m_Annots.push_back(pLeftTopAnnot);
-          sa.erase(sa.begin() + nLeftTopIndex);
-
-          std::vector<int> aSelect;
-          for (size_t i = 0; i < sa.size(); ++i) {
-            CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
-            FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f;
-            if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top)
-              aSelect.push_back(i);
-          }
-          for (size_t i = 0; i < aSelect.size(); ++i)
-            m_Annots.push_back(sa[aSelect[i]]);
-
-          for (int i = aSelect.size() - 1; i >= 0; --i)
-            sa.erase(sa.begin() + aSelect[i]);
-        }
-      }
-    } break;
-    case COLUMN: {
-      std::vector<CPDFSDK_Annot*> sa;
-      for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
-        CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
-        if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
-          sa.push_back(pAnnot);
-      }
-
-      std::sort(sa.begin(), sa.end(), CompareByTopDescending);
-      while (!sa.empty()) {
-        int nLeftTopIndex = -1;
-        FX_FLOAT fLeft = -1.0f;
-        for (int i = sa.size() - 1; i >= 0; --i) {
-          CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
-          if (fLeft < 0) {
-            nLeftTopIndex = 0;
-            fLeft = rcAnnot.left;
-          } else if (rcAnnot.left < fLeft) {
-            nLeftTopIndex = i;
-            fLeft = rcAnnot.left;
-          }
-        }
-
-        if (nLeftTopIndex >= 0) {
-          CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex];
-          CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
-          m_Annots.push_back(pLeftTopAnnot);
-          sa.erase(sa.begin() + nLeftTopIndex);
-
-          std::vector<int> aSelect;
-          for (size_t i = 0; i < sa.size(); ++i) {
-            CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
-            FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f;
-            if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right)
-              aSelect.push_back(i);
-          }
-          for (size_t i = 0; i < aSelect.size(); ++i)
-            m_Annots.push_back(sa[aSelect[i]]);
-
-          for (int i = aSelect.size() - 1; i >= 0; --i)
-            sa.erase(sa.begin() + aSelect[i]);
-        }
-      }
-      break;
-    }
-  }
-}
-
-CFX_FloatRect CBA_AnnotIterator::GetAnnotRect(const CPDFSDK_Annot* pAnnot) {
-  CFX_FloatRect rcAnnot;
-  pAnnot->GetPDFAnnot()->GetRect(rcAnnot);
-  return rcAnnot;
-}
diff --git a/fpdfsdk/cpdfsdk_xfaannothandler.cpp b/fpdfsdk/cpdfsdk_xfaannothandler.cpp
index 8c97f1d..8b1ed5c 100644
--- a/fpdfsdk/cpdfsdk_xfaannothandler.cpp
+++ b/fpdfsdk/cpdfsdk_xfaannothandler.cpp
@@ -11,6 +11,8 @@
 #include "core/fpdfdoc/include/cpdf_interform.h"
 #include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h"
 #include "fpdfsdk/include/cpdfsdk_annot.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
+#include "fpdfsdk/include/cpdfsdk_xfawidget.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "xfa/fxfa/include/fxfa_basic.h"
 #include "xfa/fxfa/include/xfa_ffdocview.h"
diff --git a/fpdfsdk/cpdfsdk_xfawidget.cpp b/fpdfsdk/cpdfsdk_xfawidget.cpp
new file mode 100644
index 0000000..b866156
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_xfawidget.cpp
@@ -0,0 +1,40 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/include/cpdfsdk_xfawidget.h"
+
+#include "fpdfsdk/include/ipdfsdk_annothandler.h"
+#include "xfa/fxfa/include/xfa_ffwidget.h"
+
+CPDFSDK_XFAWidget::CPDFSDK_XFAWidget(CXFA_FFWidget* pAnnot,
+                                     CPDFSDK_PageView* pPageView,
+                                     CPDFSDK_InterForm* pInterForm)
+    : CPDFSDK_Annot(pPageView),
+      m_pInterForm(pInterForm),
+      m_hXFAWidget(pAnnot) {}
+
+FX_BOOL CPDFSDK_XFAWidget::IsXFAField() {
+  return TRUE;
+}
+
+CXFA_FFWidget* CPDFSDK_XFAWidget::GetXFAWidget() const {
+  return m_hXFAWidget;
+}
+
+CFX_ByteString CPDFSDK_XFAWidget::GetType() const {
+  return FSDK_XFAWIDGET_TYPENAME;
+}
+
+CFX_ByteString CPDFSDK_XFAWidget::GetSubType() const {
+  return "";
+}
+
+CFX_FloatRect CPDFSDK_XFAWidget::GetRect() const {
+  CFX_RectF rcBBox;
+  GetXFAWidget()->GetRect(rcBBox);
+  return CFX_FloatRect(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
+                       rcBBox.top + rcBBox.height);
+}
diff --git a/fpdfsdk/formfiller/cffl_checkbox.cpp b/fpdfsdk/formfiller/cffl_checkbox.cpp
index 3d8f3f5..ed81f37 100644
--- a/fpdfsdk/formfiller/cffl_checkbox.cpp
+++ b/fpdfsdk/formfiller/cffl_checkbox.cpp
@@ -7,6 +7,7 @@
 #include "fpdfsdk/formfiller/cffl_checkbox.h"
 
 #include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "fpdfsdk/pdfwindow/PWL_SpecialButton.h"
 #include "public/fpdf_fwlevent.h"
diff --git a/fpdfsdk/formfiller/cffl_combobox.cpp b/fpdfsdk/formfiller/cffl_combobox.cpp
index d66977a..35591cf 100644
--- a/fpdfsdk/formfiller/cffl_combobox.cpp
+++ b/fpdfsdk/formfiller/cffl_combobox.cpp
@@ -9,6 +9,7 @@
 #include "fpdfsdk/formfiller/cba_fontmap.h"
 #include "fpdfsdk/formfiller/cffl_formfiller.h"
 #include "fpdfsdk/formfiller/cffl_iformfiller.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 #include "fpdfsdk/include/fsdk_common.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "fpdfsdk/pdfwindow/PWL_ComboBox.h"
diff --git a/fpdfsdk/formfiller/cffl_formfiller.cpp b/fpdfsdk/formfiller/cffl_formfiller.cpp
index 570654a..f2c3464 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_formfiller.cpp
@@ -8,6 +8,7 @@
 
 #include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
 #include "core/fxge/include/cfx_renderdevice.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 #include "fpdfsdk/formfiller/cba_fontmap.h"
 #include "fpdfsdk/include/fsdk_common.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
diff --git a/fpdfsdk/formfiller/cffl_formfiller.h b/fpdfsdk/formfiller/cffl_formfiller.h
index 7ae724d..b1e3231 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.h
+++ b/fpdfsdk/formfiller/cffl_formfiller.h
@@ -11,7 +11,7 @@
 
 #include "fpdfsdk/formfiller/cba_fontmap.h"
 #include "fpdfsdk/formfiller/cffl_iformfiller.h"
-#include "fpdfsdk/include/fsdk_baseform.h"
+#include "fpdfsdk/include/pdfsdk_fieldaction.h"
 
 class CPDFDoc_Environment;
 class CPDFSDK_Annot;
diff --git a/fpdfsdk/formfiller/cffl_iformfiller.cpp b/fpdfsdk/formfiller/cffl_iformfiller.cpp
index e03fa73..9e252cb 100644
--- a/fpdfsdk/formfiller/cffl_iformfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_iformfiller.cpp
@@ -18,6 +18,8 @@
 #include "fpdfsdk/formfiller/cffl_pushbutton.h"
 #include "fpdfsdk/formfiller/cffl_radiobutton.h"
 #include "fpdfsdk/formfiller/cffl_textfield.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "fpdfsdk/pdfwindow/PWL_Utils.h"
 
diff --git a/fpdfsdk/formfiller/cffl_listbox.cpp b/fpdfsdk/formfiller/cffl_listbox.cpp
index a70a1f3..36950bd 100644
--- a/fpdfsdk/formfiller/cffl_listbox.cpp
+++ b/fpdfsdk/formfiller/cffl_listbox.cpp
@@ -9,6 +9,7 @@
 #include "fpdfsdk/formfiller/cba_fontmap.h"
 #include "fpdfsdk/formfiller/cffl_formfiller.h"
 #include "fpdfsdk/formfiller/cffl_iformfiller.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 #include "fpdfsdk/include/fsdk_common.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "fpdfsdk/pdfwindow/PWL_ListBox.h"
diff --git a/fpdfsdk/formfiller/cffl_radiobutton.cpp b/fpdfsdk/formfiller/cffl_radiobutton.cpp
index 1e48849..d5474f9 100644
--- a/fpdfsdk/formfiller/cffl_radiobutton.cpp
+++ b/fpdfsdk/formfiller/cffl_radiobutton.cpp
@@ -7,6 +7,7 @@
 #include "fpdfsdk/formfiller/cffl_radiobutton.h"
 
 #include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "fpdfsdk/pdfwindow/PWL_SpecialButton.h"
 
diff --git a/fpdfsdk/formfiller/cffl_textfield.cpp b/fpdfsdk/formfiller/cffl_textfield.cpp
index 76f4b74..aaa096a 100644
--- a/fpdfsdk/formfiller/cffl_textfield.cpp
+++ b/fpdfsdk/formfiller/cffl_textfield.cpp
@@ -7,6 +7,7 @@
 #include "fpdfsdk/formfiller/cffl_textfield.h"
 
 #include "fpdfsdk/formfiller/cba_fontmap.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 #include "fpdfsdk/include/fsdk_common.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 
diff --git a/fpdfsdk/fpdfformfill.cpp b/fpdfsdk/fpdfformfill.cpp
index 8d5b4b7..263f5bb 100644
--- a/fpdfsdk/fpdfformfill.cpp
+++ b/fpdfsdk/fpdfformfill.cpp
@@ -16,6 +16,7 @@
 #include "core/fpdfdoc/include/cpdf_formfield.h"
 #include "core/fpdfdoc/include/cpdf_interform.h"
 #include "core/fxge/include/cfx_fxgedevice.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
 #include "fpdfsdk/include/fsdk_define.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "public/fpdfview.h"
diff --git a/fpdfsdk/fpdfxfa/fpdfxfa_doc.cpp b/fpdfsdk/fpdfxfa/fpdfxfa_doc.cpp
index 2b8b7e3..605e53c 100644
--- a/fpdfsdk/fpdfxfa/fpdfxfa_doc.cpp
+++ b/fpdfsdk/fpdfxfa/fpdfxfa_doc.cpp
@@ -14,6 +14,7 @@
 #include "fpdfsdk/fpdfxfa/include/fpdfxfa_page.h"
 #include "fpdfsdk/fpdfxfa/include/fpdfxfa_util.h"
 #include "fpdfsdk/include/fsdk_define.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "fpdfsdk/javascript/ijs_runtime.h"
 #include "public/fpdf_formfill.h"
diff --git a/fpdfsdk/fsdk_actionhandler.cpp b/fpdfsdk/fsdk_actionhandler.cpp
index be61ba4..c755d72 100644
--- a/fpdfsdk/fsdk_actionhandler.cpp
+++ b/fpdfsdk/fsdk_actionhandler.cpp
@@ -11,6 +11,7 @@
 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
 #include "core/fpdfdoc/include/cpdf_formfield.h"
 #include "core/fpdfdoc/include/cpdf_interform.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
 #include "fpdfsdk/include/fsdk_define.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "fpdfsdk/javascript/ijs_context.h"
diff --git a/fpdfsdk/fsdk_baseform_embeddertest.cpp b/fpdfsdk/fsdk_baseform_embeddertest.cpp
index 4fd3bb7..622f1a8 100644
--- a/fpdfsdk/fsdk_baseform_embeddertest.cpp
+++ b/fpdfsdk/fsdk_baseform_embeddertest.cpp
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "fpdfsdk/include/fsdk_baseform.h"
+#include "fpdfsdk/include/cba_annotiterator.h"
 #include "fpdfsdk/include/fsdk_define.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "testing/embedder_test.h"
diff --git a/fpdfsdk/fsdk_mgr.cpp b/fpdfsdk/fsdk_mgr.cpp
index 144bea4..932bcec 100644
--- a/fpdfsdk/fsdk_mgr.cpp
+++ b/fpdfsdk/fsdk_mgr.cpp
@@ -19,6 +19,8 @@
 #include "fpdfsdk/formfiller/cffl_formfiller.h"
 #include "fpdfsdk/include/cpdfsdk_annothandlermgr.h"
 #include "fpdfsdk/include/cpdfsdk_annotiterator.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 #include "fpdfsdk/include/fsdk_define.h"
 #include "fpdfsdk/include/ipdfsdk_annothandler.h"
 #include "fpdfsdk/javascript/ijs_runtime.h"
diff --git a/fpdfsdk/include/cba_annotiterator.h b/fpdfsdk/include/cba_annotiterator.h
new file mode 100644
index 0000000..6161cbc
--- /dev/null
+++ b/fpdfsdk/include/cba_annotiterator.h
@@ -0,0 +1,49 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_INCLUDE_CBA_ANNOTITERATOR_H_
+#define FPDFSDK_INCLUDE_CBA_ANNOTITERATOR_H_
+
+#include <vector>
+
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/fx_string.h"
+
+class CPDFSDK_Annot;
+class CPDFSDK_PageView;
+
+class CBA_AnnotIterator {
+ public:
+  enum TabOrder { STRUCTURE = 0, ROW, COLUMN };
+
+  CBA_AnnotIterator(CPDFSDK_PageView* pPageView,
+                    const CFX_ByteString& sType,
+                    const CFX_ByteString& sSubType);
+  ~CBA_AnnotIterator();
+
+  CPDFSDK_Annot* GetFirstAnnot();
+  CPDFSDK_Annot* GetLastAnnot();
+  CPDFSDK_Annot* GetNextAnnot(CPDFSDK_Annot* pAnnot);
+  CPDFSDK_Annot* GetPrevAnnot(CPDFSDK_Annot* pAnnot);
+
+ private:
+  void GenerateResults();
+  static CFX_FloatRect GetAnnotRect(const CPDFSDK_Annot* pAnnot);
+
+  // Function signature compatible with std::sort().
+  static bool CompareByLeftAscending(const CPDFSDK_Annot* p1,
+                                     const CPDFSDK_Annot* p2);
+  static bool CompareByTopDescending(const CPDFSDK_Annot* p1,
+                                     const CPDFSDK_Annot* p2);
+
+  TabOrder m_eTabOrder;
+  CPDFSDK_PageView* m_pPageView;
+  CFX_ByteString m_sType;
+  CFX_ByteString m_sSubType;
+  std::vector<CPDFSDK_Annot*> m_Annots;
+};
+
+#endif  // FPDFSDK_INCLUDE_CBA_ANNOTITERATOR_H_
diff --git a/fpdfsdk/include/cpdfsdk_interform.h b/fpdfsdk/include/cpdfsdk_interform.h
new file mode 100644
index 0000000..2fd93f1
--- /dev/null
+++ b/fpdfsdk/include/cpdfsdk_interform.h
@@ -0,0 +1,144 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_INCLUDE_CPDFSDK_INTERFORM_H_
+#define FPDFSDK_INCLUDE_CPDFSDK_INTERFORM_H_
+
+#include <map>
+#include <vector>
+
+#include "core/fpdfdoc/include/cpdf_action.h"
+#include "core/fpdfdoc/include/ipdf_formnotify.h"
+#include "core/fxcrt/include/fx_basic.h"
+#include "core/fxge/include/fx_dib.h"
+
+class CPDF_Dictionary;
+class CPDF_FormControl;
+class CPDF_FormField;
+class CPDF_InterForm;
+class CPDF_Object;
+class CPDFSDK_Document;
+class CPDFSDK_Widget;
+
+#ifdef PDF_ENABLE_XFA
+class CPDFSDK_XFAWidget;
+class CXFA_FFWidget;
+#endif  // PDF_ENABLE_XFA
+
+class CPDFSDK_InterForm : public IPDF_FormNotify {
+ public:
+  explicit CPDFSDK_InterForm(CPDFSDK_Document* pDocument);
+  ~CPDFSDK_InterForm() override;
+
+  CPDF_InterForm* GetInterForm() const { return m_pInterForm.get(); }
+  CPDFSDK_Document* GetDocument() const { return m_pDocument; }
+
+  FX_BOOL HighlightWidgets();
+
+  CPDFSDK_Widget* GetSibling(CPDFSDK_Widget* pWidget, FX_BOOL bNext) const;
+  CPDFSDK_Widget* GetWidget(CPDF_FormControl* pControl,
+                            bool createIfNeeded) const;
+  void GetWidgets(const CFX_WideString& sFieldName,
+                  std::vector<CPDFSDK_Widget*>* widgets) const;
+  void GetWidgets(CPDF_FormField* pField,
+                  std::vector<CPDFSDK_Widget*>* widgets) const;
+
+  void AddMap(CPDF_FormControl* pControl, CPDFSDK_Widget* pWidget);
+  void RemoveMap(CPDF_FormControl* pControl);
+
+  void EnableCalculate(FX_BOOL bEnabled);
+  FX_BOOL IsCalculateEnabled() const;
+
+#ifdef PDF_ENABLE_XFA
+  void AddXFAMap(CXFA_FFWidget* hWidget, CPDFSDK_XFAWidget* pWidget);
+  void RemoveXFAMap(CXFA_FFWidget* hWidget);
+  CPDFSDK_XFAWidget* GetXFAWidget(CXFA_FFWidget* hWidget);
+  void XfaEnableCalculate(FX_BOOL bEnabled);
+  FX_BOOL IsXfaCalculateEnabled() const;
+  FX_BOOL IsXfaValidationsEnabled();
+  void XfaSetValidationsEnabled(FX_BOOL bEnabled);
+  void SynchronizeField(CPDF_FormField* pFormField, FX_BOOL bSynchronizeElse);
+#endif  // PDF_ENABLE_XFA
+
+  FX_BOOL OnKeyStrokeCommit(CPDF_FormField* pFormField,
+                            const CFX_WideString& csValue);
+  FX_BOOL OnValidate(CPDF_FormField* pFormField, const CFX_WideString& csValue);
+  void OnCalculate(CPDF_FormField* pFormField = nullptr);
+  CFX_WideString OnFormat(CPDF_FormField* pFormField, FX_BOOL& bFormated);
+
+  void ResetFieldAppearance(CPDF_FormField* pFormField,
+                            const FX_WCHAR* sValue,
+                            FX_BOOL bValueChanged);
+  void UpdateField(CPDF_FormField* pFormField);
+
+  FX_BOOL DoAction_Hide(const CPDF_Action& action);
+  FX_BOOL DoAction_SubmitForm(const CPDF_Action& action);
+  FX_BOOL DoAction_ResetForm(const CPDF_Action& action);
+  FX_BOOL DoAction_ImportData(const CPDF_Action& action);
+
+  std::vector<CPDF_FormField*> GetFieldFromObjects(
+      const std::vector<CPDF_Object*>& objects) const;
+  FX_BOOL IsValidField(CPDF_Dictionary* pFieldDict);
+  FX_BOOL SubmitFields(const CFX_WideString& csDestination,
+                       const std::vector<CPDF_FormField*>& fields,
+                       bool bIncludeOrExclude,
+                       bool bUrlEncoded);
+  FX_BOOL SubmitForm(const CFX_WideString& sDestination, FX_BOOL bUrlEncoded);
+  FX_BOOL ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf);
+  FX_BOOL ExportFieldsToFDFTextBuf(const std::vector<CPDF_FormField*>& fields,
+                                   bool bIncludeOrExclude,
+                                   CFX_ByteTextBuf& textBuf);
+  CFX_WideString GetTemporaryFileName(const CFX_WideString& sFileExt);
+
+  FX_BOOL IsNeedHighLight(int nFieldType);
+  void RemoveAllHighLight();
+  void SetHighlightAlpha(uint8_t alpha) { m_iHighlightAlpha = alpha; }
+  uint8_t GetHighlightAlpha() { return m_iHighlightAlpha; }
+  void SetHighlightColor(FX_COLORREF clr, int nFieldType);
+  FX_COLORREF GetHighlightColor(int nFieldType);
+
+ private:
+  // IPDF_FormNotify:
+  int BeforeValueChange(CPDF_FormField* pField,
+                        const CFX_WideString& csValue) override;
+  void AfterValueChange(CPDF_FormField* pField) override;
+  int BeforeSelectionChange(CPDF_FormField* pField,
+                            const CFX_WideString& csValue) override;
+  void AfterSelectionChange(CPDF_FormField* pField) override;
+  void AfterCheckedStatusChange(CPDF_FormField* pField) override;
+  int BeforeFormReset(CPDF_InterForm* pForm) override;
+  void AfterFormReset(CPDF_InterForm* pForm) override;
+  int BeforeFormImportData(CPDF_InterForm* pForm) override;
+  void AfterFormImportData(CPDF_InterForm* pForm) override;
+
+  FX_BOOL FDFToURLEncodedData(CFX_WideString csFDFFile,
+                              CFX_WideString csTxtFile);
+  FX_BOOL FDFToURLEncodedData(uint8_t*& pBuf, FX_STRSIZE& nBufSize);
+  int GetPageIndexByAnnotDict(CPDF_Document* pDocument,
+                              CPDF_Dictionary* pAnnotDict) const;
+
+  using CPDFSDK_WidgetMap = std::map<CPDF_FormControl*, CPDFSDK_Widget*>;
+
+  CPDFSDK_Document* m_pDocument;
+  std::unique_ptr<CPDF_InterForm> m_pInterForm;
+  CPDFSDK_WidgetMap m_Map;
+#ifdef PDF_ENABLE_XFA
+  std::map<CXFA_FFWidget*, CPDFSDK_XFAWidget*> m_XFAMap;
+  FX_BOOL m_bXfaCalculate;
+  FX_BOOL m_bXfaValidationsEnabled;
+  static const int kNumFieldTypes = 7;
+#else   // PDF_ENABLE_XFA
+  static const int kNumFieldTypes = 6;
+#endif  // PDF_ENABLE_XFA
+  FX_BOOL m_bCalculate;
+  FX_BOOL m_bBusy;
+
+  FX_COLORREF m_aHighlightColor[kNumFieldTypes];
+  uint8_t m_iHighlightAlpha;
+  FX_BOOL m_bNeedHightlight[kNumFieldTypes];
+};
+
+#endif  // FPDFSDK_INCLUDE_CPDFSDK_INTERFORM_H_
diff --git a/fpdfsdk/include/cpdfsdk_widget.h b/fpdfsdk/include/cpdfsdk_widget.h
new file mode 100644
index 0000000..7f5e345
--- /dev/null
+++ b/fpdfsdk/include/cpdfsdk_widget.h
@@ -0,0 +1,191 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_INCLUDE_CPDFSDK_WIDGET_H_
+#define FPDFSDK_INCLUDE_CPDFSDK_WIDGET_H_
+
+#include <set>
+
+#include "core/fpdfdoc/include/cpdf_aaction.h"
+#include "core/fpdfdoc/include/cpdf_action.h"
+#include "core/fpdfdoc/include/cpdf_annot.h"
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/fx_string.h"
+#include "fpdfsdk/include/cpdfsdk_baannot.h"
+#include "fpdfsdk/include/pdfsdk_fieldaction.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+
+class CFX_RenderDevice;
+class CPDF_Annot;
+class CPDF_Dictionary;
+class CPDF_FormControl;
+class CPDF_FormField;
+class CPDF_RenderOptions;
+class CPDF_Stream;
+class CPDFSDK_InterForm;
+class CPDFSDK_PageView;
+
+#ifdef PDF_ENABLE_XFA
+class CXFA_FFWidget;
+class CXFA_FFWidgetHandler;
+#endif  // PDF_ENABLE_XFA
+
+class CPDFSDK_Widget : public CPDFSDK_BAAnnot {
+ public:
+  class Observer {
+   public:
+    explicit Observer(CPDFSDK_Widget** pWatchedPtr);
+    ~Observer();
+
+    void OnWidgetDestroyed();
+
+   private:
+    CPDFSDK_Widget** m_pWatchedPtr;
+  };
+
+#ifdef PDF_ENABLE_XFA
+  CXFA_FFWidget* GetMixXFAWidget() const;
+  CXFA_FFWidget* GetGroupMixXFAWidget();
+  CXFA_FFWidgetHandler* GetXFAWidgetHandler() const;
+
+  FX_BOOL HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT);
+  FX_BOOL OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
+                       PDFSDK_FieldAction& data,
+                       CPDFSDK_PageView* pPageView);
+
+  void Synchronize(FX_BOOL bSynchronizeElse);
+  void SynchronizeXFAValue();
+  void SynchronizeXFAItems();
+
+  static void SynchronizeXFAValue(CXFA_FFDocView* pXFADocView,
+                                  CXFA_FFWidget* hWidget,
+                                  CPDF_FormField* pFormField,
+                                  CPDF_FormControl* pFormControl);
+  static void SynchronizeXFAItems(CXFA_FFDocView* pXFADocView,
+                                  CXFA_FFWidget* hWidget,
+                                  CPDF_FormField* pFormField,
+                                  CPDF_FormControl* pFormControl);
+#endif  // PDF_ENABLE_XFA
+
+  CPDFSDK_Widget(CPDF_Annot* pAnnot,
+                 CPDFSDK_PageView* pPageView,
+                 CPDFSDK_InterForm* pInterForm);
+  ~CPDFSDK_Widget() override;
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+  CFX_ByteString GetSubType() const override;
+  CPDF_Action GetAAction(CPDF_AAction::AActionType eAAT) override;
+  FX_BOOL IsAppearanceValid() override;
+
+  int GetLayoutOrder() const override;
+
+  int GetFieldType() const;
+  int GetFieldFlags() const;
+  int GetRotate() const;
+
+  FX_BOOL GetFillColor(FX_COLORREF& color) const;
+  FX_BOOL GetBorderColor(FX_COLORREF& color) const;
+  FX_BOOL GetTextColor(FX_COLORREF& color) const;
+  FX_FLOAT GetFontSize() const;
+
+  int GetSelectedIndex(int nIndex) const;
+#ifndef PDF_ENABLE_XFA
+  CFX_WideString GetValue() const;
+#else
+  CFX_WideString GetValue(FX_BOOL bDisplay = TRUE) const;
+#endif  // PDF_ENABLE_XFA
+  CFX_WideString GetDefaultValue() const;
+  CFX_WideString GetOptionLabel(int nIndex) const;
+  int CountOptions() const;
+  FX_BOOL IsOptionSelected(int nIndex) const;
+  int GetTopVisibleIndex() const;
+  bool IsChecked() const;
+  int GetAlignment() const;
+  int GetMaxLen() const;
+#ifdef PDF_ENABLE_XFA
+  CFX_WideString GetName() const;
+#endif  // PDF_ENABLE_XFA
+  CFX_WideString GetAlternateName() const;
+
+  void SetCheck(bool bChecked, bool bNotify);
+  void SetValue(const CFX_WideString& sValue, FX_BOOL bNotify);
+  void SetDefaultValue(const CFX_WideString& sValue);
+  void SetOptionSelection(int index, FX_BOOL bSelected, FX_BOOL bNotify);
+  void ClearSelection(FX_BOOL bNotify);
+  void SetTopVisibleIndex(int index);
+
+#ifdef PDF_ENABLE_XFA
+  void ResetAppearance(FX_BOOL bValueChanged);
+#endif  // PDF_ENABLE_XFA
+  void ResetAppearance(const FX_WCHAR* sValue, FX_BOOL bValueChanged);
+  void ResetFieldAppearance(FX_BOOL bValueChanged);
+  void UpdateField();
+  CFX_WideString OnFormat(FX_BOOL& bFormated);
+
+  FX_BOOL OnAAction(CPDF_AAction::AActionType type,
+                    PDFSDK_FieldAction& data,
+                    CPDFSDK_PageView* pPageView);
+
+  CPDFSDK_InterForm* GetInterForm() const { return m_pInterForm; }
+  CPDF_FormField* GetFormField() const;
+  CPDF_FormControl* GetFormControl() const;
+  static CPDF_FormControl* GetFormControl(CPDF_InterForm* pInterForm,
+                                          const CPDF_Dictionary* pAnnotDict);
+
+  void DrawShadow(CFX_RenderDevice* pDevice, CPDFSDK_PageView* pPageView);
+
+  void SetAppModified();
+  void ClearAppModified();
+  FX_BOOL IsAppModified() const;
+
+  int32_t GetAppearanceAge() const;
+  int32_t GetValueAge() const;
+
+  FX_BOOL IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode);
+  void DrawAppearance(CFX_RenderDevice* pDevice,
+                      const CFX_Matrix* pUser2Device,
+                      CPDF_Annot::AppearanceMode mode,
+                      const CPDF_RenderOptions* pOptions) override;
+
+  FX_BOOL HitTest(FX_FLOAT pageX, FX_FLOAT pageY);
+
+ private:
+  void ResetAppearance_PushButton();
+  void ResetAppearance_CheckBox();
+  void ResetAppearance_RadioButton();
+  void ResetAppearance_ComboBox(const FX_WCHAR* sValue);
+  void ResetAppearance_ListBox();
+  void ResetAppearance_TextField(const FX_WCHAR* sValue);
+
+  CFX_FloatRect GetClientRect() const;
+  CFX_FloatRect GetRotatedRect() const;
+
+  CFX_ByteString GetBackgroundAppStream() const;
+  CFX_ByteString GetBorderAppStream() const;
+  CFX_Matrix GetMatrix() const;
+
+  CPWL_Color GetTextPWLColor() const;
+  CPWL_Color GetBorderPWLColor() const;
+  CPWL_Color GetFillPWLColor() const;
+
+  void AddImageToAppearance(const CFX_ByteString& sAPType, CPDF_Stream* pImage);
+  void RemoveAppearance(const CFX_ByteString& sAPType);
+
+  CPDFSDK_InterForm* const m_pInterForm;
+  FX_BOOL m_bAppModified;
+  int32_t m_nAppAge;
+  int32_t m_nValueAge;
+  std::set<Observer*> m_Observers;
+
+#ifdef PDF_ENABLE_XFA
+  mutable CXFA_FFWidget* m_hMixXFAWidget;
+  mutable CXFA_FFWidgetHandler* m_pWidgetHandler;
+#endif  // PDF_ENABLE_XFA
+};
+
+#endif  // FPDFSDK_INCLUDE_CPDFSDK_WIDGET_H_
diff --git a/fpdfsdk/include/cpdfsdk_xfawidget.h b/fpdfsdk/include/cpdfsdk_xfawidget.h
new file mode 100644
index 0000000..46e71b6
--- /dev/null
+++ b/fpdfsdk/include/cpdfsdk_xfawidget.h
@@ -0,0 +1,38 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_INCLUDE_CPDFSDK_XFAWIDGET_H_
+#define FPDFSDK_INCLUDE_CPDFSDK_XFAWIDGET_H_
+
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/fx_string.h"
+#include "fpdfsdk/include/cpdfsdk_annot.h"
+
+class CPDFSDK_InterForm;
+class CPDFSDK_PageView;
+class CXFA_FFWidget;
+
+class CPDFSDK_XFAWidget : public CPDFSDK_Annot {
+ public:
+  CPDFSDK_XFAWidget(CXFA_FFWidget* pAnnot,
+                    CPDFSDK_PageView* pPageView,
+                    CPDFSDK_InterForm* pInterForm);
+  ~CPDFSDK_XFAWidget() override {}
+
+  FX_BOOL IsXFAField() override;
+  CXFA_FFWidget* GetXFAWidget() const override;
+  CFX_ByteString GetType() const override;
+  CFX_ByteString GetSubType() const override;
+  CFX_FloatRect GetRect() const override;
+
+  CPDFSDK_InterForm* GetInterForm() { return m_pInterForm; }
+
+ private:
+  CPDFSDK_InterForm* m_pInterForm;
+  CXFA_FFWidget* m_hXFAWidget;
+};
+
+#endif  // FPDFSDK_INCLUDE_CPDFSDK_XFAWIDGET_H_
diff --git a/fpdfsdk/include/fsdk_actionhandler.h b/fpdfsdk/include/fsdk_actionhandler.h
index 66ec69e..f488251 100644
--- a/fpdfsdk/include/fsdk_actionhandler.h
+++ b/fpdfsdk/include/fsdk_actionhandler.h
@@ -10,13 +10,16 @@
 #include <memory>
 #include <set>
 
+#include "core/fpdfdoc/include/cpdf_action.h"
+#include "core/fpdfdoc/include/cpdf_aaction.h"
 #include "core/fxcrt/include/fx_string.h"
-#include "fpdfsdk/include/fsdk_baseform.h"
+#include "fpdfsdk/include/pdfsdk_fieldaction.h"
 
 class CPDFSDK_Annot;
 class CPDFSDK_Document;
 class CPDF_Bookmark;
 class CPDF_Dictionary;
+class CPDF_FormField;
 
 class CPDFSDK_ActionHandler {
  public:
diff --git a/fpdfsdk/include/fsdk_baseform.h b/fpdfsdk/include/fsdk_baseform.h
deleted file mode 100644
index 8eee56c..0000000
--- a/fpdfsdk/include/fsdk_baseform.h
+++ /dev/null
@@ -1,407 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef FPDFSDK_INCLUDE_FSDK_BASEFORM_H_
-#define FPDFSDK_INCLUDE_FSDK_BASEFORM_H_
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "core/fpdfdoc/include/ipdf_formnotify.h"
-#include "core/fxcrt/include/fx_basic.h"
-#include "core/fxge/include/fx_dib.h"
-#include "fpdfsdk/include/cpdfsdk_annot.h"
-#include "fpdfsdk/include/cpdfsdk_baannot.h"
-
-#if _FX_OS_ == _FX_ANDROID_
-#include "time.h"
-#else
-#include <ctime>
-#endif
-
-class CPDFSDK_Annot;
-class CPDFSDK_Document;
-class CPDFSDK_InterForm;
-class CPDFSDK_PageView;
-class CPDF_Action;
-class CPDF_FormControl;
-class CPDF_FormField;
-class CPDF_InterForm;
-struct CPWL_Color;
-
-#ifdef PDF_ENABLE_XFA
-class CXFA_FFWidgetHandler;
-
-typedef enum _PDFSDK_XFAAActionType {
-  PDFSDK_XFA_Click = 0,
-  PDFSDK_XFA_Full,
-  PDFSDK_XFA_PreOpen,
-  PDFSDK_XFA_PostOpen
-} PDFSDK_XFAAActionType;
-#endif  // PDF_ENABLE_XFA
-
-struct PDFSDK_FieldAction {
-  PDFSDK_FieldAction();
-  PDFSDK_FieldAction(const PDFSDK_FieldAction& other) = delete;
-
-  FX_BOOL bModifier;         // in
-  FX_BOOL bShift;            // in
-  int nCommitKey;            // in
-  CFX_WideString sChange;    // in[out]
-  CFX_WideString sChangeEx;  // in
-  FX_BOOL bKeyDown;          // in
-  int nSelEnd;               // in[out]
-  int nSelStart;             // in[out]
-  CFX_WideString sValue;     // in[out]
-  FX_BOOL bWillCommit;       // in
-  FX_BOOL bFieldFull;        // in
-  FX_BOOL bRC;               // in[out]
-};
-
-class CPDFSDK_Widget : public CPDFSDK_BAAnnot {
- public:
-  class Observer {
-   public:
-    explicit Observer(CPDFSDK_Widget** pWatchedPtr);
-    ~Observer();
-
-    void OnWidgetDestroyed();
-
-   private:
-    CPDFSDK_Widget** m_pWatchedPtr;
-  };
-
-#ifdef PDF_ENABLE_XFA
-  CXFA_FFWidget* GetMixXFAWidget() const;
-  CXFA_FFWidget* GetGroupMixXFAWidget();
-  CXFA_FFWidgetHandler* GetXFAWidgetHandler() const;
-
-  FX_BOOL HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT);
-  FX_BOOL OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
-                       PDFSDK_FieldAction& data,
-                       CPDFSDK_PageView* pPageView);
-
-  void Synchronize(FX_BOOL bSynchronizeElse);
-  void SynchronizeXFAValue();
-  void SynchronizeXFAItems();
-
-  static void SynchronizeXFAValue(CXFA_FFDocView* pXFADocView,
-                                  CXFA_FFWidget* hWidget,
-                                  CPDF_FormField* pFormField,
-                                  CPDF_FormControl* pFormControl);
-  static void SynchronizeXFAItems(CXFA_FFDocView* pXFADocView,
-                                  CXFA_FFWidget* hWidget,
-                                  CPDF_FormField* pFormField,
-                                  CPDF_FormControl* pFormControl);
-#endif  // PDF_ENABLE_XFA
-
-  CPDFSDK_Widget(CPDF_Annot* pAnnot,
-                 CPDFSDK_PageView* pPageView,
-                 CPDFSDK_InterForm* pInterForm);
-  ~CPDFSDK_Widget() override;
-
-  void AddObserver(Observer* observer);
-  void RemoveObserver(Observer* observer);
-
-  // CPDFSDK_Annot
-  CFX_ByteString GetSubType() const override;
-  CPDF_Action GetAAction(CPDF_AAction::AActionType eAAT) override;
-  FX_BOOL IsAppearanceValid() override;
-
-  int GetLayoutOrder() const override;
-
-  int GetFieldType() const;
-
-  // Possible values from PDF 32000-1:2008, table 221.
-  // FIELDFLAG_READONLY
-  // FIELDFLAG_REQUIRED
-  // FIELDFLAG_NOEXPORT
-  int GetFieldFlags() const;
-  int GetRotate() const;
-
-  FX_BOOL GetFillColor(FX_COLORREF& color) const;
-  FX_BOOL GetBorderColor(FX_COLORREF& color) const;
-  FX_BOOL GetTextColor(FX_COLORREF& color) const;
-  FX_FLOAT GetFontSize() const;
-
-  int GetSelectedIndex(int nIndex) const;
-#ifndef PDF_ENABLE_XFA
-  CFX_WideString GetValue() const;
-#else
-  CFX_WideString GetValue(FX_BOOL bDisplay = TRUE) const;
-#endif  // PDF_ENABLE_XFA
-  CFX_WideString GetDefaultValue() const;
-  CFX_WideString GetOptionLabel(int nIndex) const;
-  int CountOptions() const;
-  FX_BOOL IsOptionSelected(int nIndex) const;
-  int GetTopVisibleIndex() const;
-  bool IsChecked() const;
-  /*
-  BF_ALIGN_LEFT
-  BF_ALIGN_MIDDL
-  BF_ALIGN_RIGHT
-  */
-  int GetAlignment() const;
-  int GetMaxLen() const;
-#ifdef PDF_ENABLE_XFA
-  CFX_WideString GetName() const;
-#endif  // PDF_ENABLE_XFA
-  CFX_WideString GetAlternateName() const;
-
-  // Set Properties.
-  void SetCheck(bool bChecked, bool bNotify);
-  void SetValue(const CFX_WideString& sValue, FX_BOOL bNotify);
-  void SetDefaultValue(const CFX_WideString& sValue);
-  void SetOptionSelection(int index, FX_BOOL bSelected, FX_BOOL bNotify);
-  void ClearSelection(FX_BOOL bNotify);
-  void SetTopVisibleIndex(int index);
-
-#ifdef PDF_ENABLE_XFA
-  void ResetAppearance(FX_BOOL bValueChanged);
-#endif  // PDF_ENABLE_XFA
-  void ResetAppearance(const FX_WCHAR* sValue, FX_BOOL bValueChanged);
-  void ResetFieldAppearance(FX_BOOL bValueChanged);
-  void UpdateField();
-  CFX_WideString OnFormat(FX_BOOL& bFormated);
-
-  // Message.
-  FX_BOOL OnAAction(CPDF_AAction::AActionType type,
-                    PDFSDK_FieldAction& data,
-                    CPDFSDK_PageView* pPageView);
-
-  CPDFSDK_InterForm* GetInterForm() const { return m_pInterForm; }
-  CPDF_FormField* GetFormField() const;
-  CPDF_FormControl* GetFormControl() const;
-  static CPDF_FormControl* GetFormControl(CPDF_InterForm* pInterForm,
-                                          const CPDF_Dictionary* pAnnotDict);
-
-  void DrawShadow(CFX_RenderDevice* pDevice, CPDFSDK_PageView* pPageView);
-
-  void SetAppModified();
-  void ClearAppModified();
-  FX_BOOL IsAppModified() const;
-
-  int32_t GetAppearanceAge() const;
-  int32_t GetValueAge() const;
-
-  FX_BOOL IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode);
-  void DrawAppearance(CFX_RenderDevice* pDevice,
-                      const CFX_Matrix* pUser2Device,
-                      CPDF_Annot::AppearanceMode mode,
-                      const CPDF_RenderOptions* pOptions) override;
-
-  FX_BOOL HitTest(FX_FLOAT pageX, FX_FLOAT pageY);
-
- private:
-  void ResetAppearance_PushButton();
-  void ResetAppearance_CheckBox();
-  void ResetAppearance_RadioButton();
-  void ResetAppearance_ComboBox(const FX_WCHAR* sValue);
-  void ResetAppearance_ListBox();
-  void ResetAppearance_TextField(const FX_WCHAR* sValue);
-
-  CFX_FloatRect GetClientRect() const;
-  CFX_FloatRect GetRotatedRect() const;
-
-  CFX_ByteString GetBackgroundAppStream() const;
-  CFX_ByteString GetBorderAppStream() const;
-  CFX_Matrix GetMatrix() const;
-
-  CPWL_Color GetTextPWLColor() const;
-  CPWL_Color GetBorderPWLColor() const;
-  CPWL_Color GetFillPWLColor() const;
-
-  void AddImageToAppearance(const CFX_ByteString& sAPType, CPDF_Stream* pImage);
-  void RemoveAppearance(const CFX_ByteString& sAPType);
-
-  CPDFSDK_InterForm* const m_pInterForm;
-  FX_BOOL m_bAppModified;
-  int32_t m_nAppAge;
-  int32_t m_nValueAge;
-  std::set<Observer*> m_Observers;
-
-#ifdef PDF_ENABLE_XFA
-  mutable CXFA_FFWidget* m_hMixXFAWidget;
-  mutable CXFA_FFWidgetHandler* m_pWidgetHandler;
-#endif  // PDF_ENABLE_XFA
-};
-
-#ifdef PDF_ENABLE_XFA
-class CPDFSDK_XFAWidget : public CPDFSDK_Annot {
- public:
-  CPDFSDK_XFAWidget(CXFA_FFWidget* pAnnot,
-                    CPDFSDK_PageView* pPageView,
-                    CPDFSDK_InterForm* pInterForm);
-  ~CPDFSDK_XFAWidget() override {}
-
-  FX_BOOL IsXFAField() override;
-  CXFA_FFWidget* GetXFAWidget() const override;
-  CFX_ByteString GetType() const override;
-  CFX_ByteString GetSubType() const override;
-  CFX_FloatRect GetRect() const override;
-
-  CPDFSDK_InterForm* GetInterForm() { return m_pInterForm; }
-
- private:
-  CPDFSDK_InterForm* m_pInterForm;
-  CXFA_FFWidget* m_hXFAWidget;
-};
-#endif  // PDF_ENABLE_XFA
-
-class CPDFSDK_InterForm : public IPDF_FormNotify {
- public:
-  explicit CPDFSDK_InterForm(CPDFSDK_Document* pDocument);
-  ~CPDFSDK_InterForm() override;
-
-  CPDF_InterForm* GetInterForm() const { return m_pInterForm.get(); }
-  CPDFSDK_Document* GetDocument() const { return m_pDocument; }
-
-  FX_BOOL HighlightWidgets();
-
-  CPDFSDK_Widget* GetSibling(CPDFSDK_Widget* pWidget, FX_BOOL bNext) const;
-  CPDFSDK_Widget* GetWidget(CPDF_FormControl* pControl,
-                            bool createIfNeeded) const;
-  void GetWidgets(const CFX_WideString& sFieldName,
-                  std::vector<CPDFSDK_Widget*>* widgets) const;
-  void GetWidgets(CPDF_FormField* pField,
-                  std::vector<CPDFSDK_Widget*>* widgets) const;
-
-  void AddMap(CPDF_FormControl* pControl, CPDFSDK_Widget* pWidget);
-  void RemoveMap(CPDF_FormControl* pControl);
-
-  void EnableCalculate(FX_BOOL bEnabled);
-  FX_BOOL IsCalculateEnabled() const;
-
-#ifdef PDF_ENABLE_XFA
-  void AddXFAMap(CXFA_FFWidget* hWidget, CPDFSDK_XFAWidget* pWidget);
-  void RemoveXFAMap(CXFA_FFWidget* hWidget);
-  CPDFSDK_XFAWidget* GetXFAWidget(CXFA_FFWidget* hWidget);
-  void XfaEnableCalculate(FX_BOOL bEnabled);
-  FX_BOOL IsXfaCalculateEnabled() const;
-  FX_BOOL IsXfaValidationsEnabled();
-  void XfaSetValidationsEnabled(FX_BOOL bEnabled);
-#endif  // PDF_ENABLE_XFA
-
-  FX_BOOL OnKeyStrokeCommit(CPDF_FormField* pFormField,
-                            const CFX_WideString& csValue);
-  FX_BOOL OnValidate(CPDF_FormField* pFormField, const CFX_WideString& csValue);
-  void OnCalculate(CPDF_FormField* pFormField = nullptr);
-  CFX_WideString OnFormat(CPDF_FormField* pFormField, FX_BOOL& bFormated);
-
-  void ResetFieldAppearance(CPDF_FormField* pFormField,
-                            const FX_WCHAR* sValue,
-                            FX_BOOL bValueChanged);
-  void UpdateField(CPDF_FormField* pFormField);
-
-  FX_BOOL DoAction_Hide(const CPDF_Action& action);
-  FX_BOOL DoAction_SubmitForm(const CPDF_Action& action);
-  FX_BOOL DoAction_ResetForm(const CPDF_Action& action);
-  FX_BOOL DoAction_ImportData(const CPDF_Action& action);
-
-  std::vector<CPDF_FormField*> GetFieldFromObjects(
-      const std::vector<CPDF_Object*>& objects) const;
-  FX_BOOL IsValidField(CPDF_Dictionary* pFieldDict);
-  FX_BOOL SubmitFields(const CFX_WideString& csDestination,
-                       const std::vector<CPDF_FormField*>& fields,
-                       bool bIncludeOrExclude,
-                       bool bUrlEncoded);
-  FX_BOOL SubmitForm(const CFX_WideString& sDestination, FX_BOOL bUrlEncoded);
-  FX_BOOL ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf);
-  FX_BOOL ExportFieldsToFDFTextBuf(const std::vector<CPDF_FormField*>& fields,
-                                   bool bIncludeOrExclude,
-                                   CFX_ByteTextBuf& textBuf);
-  CFX_WideString GetTemporaryFileName(const CFX_WideString& sFileExt);
-
-#ifdef PDF_ENABLE_XFA
-  void SynchronizeField(CPDF_FormField* pFormField, FX_BOOL bSynchronizeElse);
-#endif  // PDF_ENABLE_XFA
-
- private:
-  // IPDF_FormNotify:
-  int BeforeValueChange(CPDF_FormField* pField,
-                        const CFX_WideString& csValue) override;
-  void AfterValueChange(CPDF_FormField* pField) override;
-  int BeforeSelectionChange(CPDF_FormField* pField,
-                            const CFX_WideString& csValue) override;
-  void AfterSelectionChange(CPDF_FormField* pField) override;
-  void AfterCheckedStatusChange(CPDF_FormField* pField) override;
-  int BeforeFormReset(CPDF_InterForm* pForm) override;
-  void AfterFormReset(CPDF_InterForm* pForm) override;
-  int BeforeFormImportData(CPDF_InterForm* pForm) override;
-  void AfterFormImportData(CPDF_InterForm* pForm) override;
-
-  FX_BOOL FDFToURLEncodedData(CFX_WideString csFDFFile,
-                              CFX_WideString csTxtFile);
-  FX_BOOL FDFToURLEncodedData(uint8_t*& pBuf, FX_STRSIZE& nBufSize);
-  int GetPageIndexByAnnotDict(CPDF_Document* pDocument,
-                              CPDF_Dictionary* pAnnotDict) const;
-
-  using CPDFSDK_WidgetMap = std::map<CPDF_FormControl*, CPDFSDK_Widget*>;
-
-  CPDFSDK_Document* m_pDocument;
-  std::unique_ptr<CPDF_InterForm> m_pInterForm;
-  CPDFSDK_WidgetMap m_Map;
-#ifdef PDF_ENABLE_XFA
-  std::map<CXFA_FFWidget*, CPDFSDK_XFAWidget*> m_XFAMap;
-  FX_BOOL m_bXfaCalculate;
-  FX_BOOL m_bXfaValidationsEnabled;
-#endif  // PDF_ENABLE_XFA
-  FX_BOOL m_bCalculate;
-  FX_BOOL m_bBusy;
-
- public:
-  FX_BOOL IsNeedHighLight(int nFieldType);
-  void RemoveAllHighLight();
-  void SetHighlightAlpha(uint8_t alpha) { m_iHighlightAlpha = alpha; }
-  uint8_t GetHighlightAlpha() { return m_iHighlightAlpha; }
-  void SetHighlightColor(FX_COLORREF clr, int nFieldType);
-  FX_COLORREF GetHighlightColor(int nFieldType);
-
- private:
-#ifndef PDF_ENABLE_XFA
-  static const int kNumFieldTypes = 6;
-#else   // PDF_ENABLE_XFA
-  static const int kNumFieldTypes = 7;
-#endif  // PDF_ENABLE_XFA
-
-  FX_COLORREF m_aHighlightColor[kNumFieldTypes];
-  uint8_t m_iHighlightAlpha;
-  FX_BOOL m_bNeedHightlight[kNumFieldTypes];
-};
-
-class CBA_AnnotIterator {
- public:
-  enum TabOrder { STRUCTURE = 0, ROW, COLUMN };
-
-  CBA_AnnotIterator(CPDFSDK_PageView* pPageView,
-                    const CFX_ByteString& sType,
-                    const CFX_ByteString& sSubType);
-  ~CBA_AnnotIterator();
-
-  CPDFSDK_Annot* GetFirstAnnot();
-  CPDFSDK_Annot* GetLastAnnot();
-  CPDFSDK_Annot* GetNextAnnot(CPDFSDK_Annot* pAnnot);
-  CPDFSDK_Annot* GetPrevAnnot(CPDFSDK_Annot* pAnnot);
-
- private:
-  void GenerateResults();
-  static CFX_FloatRect GetAnnotRect(const CPDFSDK_Annot* pAnnot);
-
-  // Function signature compatible with std::sort().
-  static bool CompareByLeftAscending(const CPDFSDK_Annot* p1,
-                                     const CPDFSDK_Annot* p2);
-  static bool CompareByTopDescending(const CPDFSDK_Annot* p1,
-                                     const CPDFSDK_Annot* p2);
-
-  TabOrder m_eTabOrder;
-  CPDFSDK_PageView* m_pPageView;
-  CFX_ByteString m_sType;
-  CFX_ByteString m_sSubType;
-  std::vector<CPDFSDK_Annot*> m_Annots;
-};
-
-#endif  // FPDFSDK_INCLUDE_FSDK_BASEFORM_H_
diff --git a/fpdfsdk/include/fsdk_mgr.h b/fpdfsdk/include/fsdk_mgr.h
index f9d382c..a93f9da 100644
--- a/fpdfsdk/include/fsdk_mgr.h
+++ b/fpdfsdk/include/fsdk_mgr.h
@@ -17,7 +17,6 @@
 #include "fpdfsdk/cfx_systemhandler.h"
 #include "fpdfsdk/include/cpdfsdk_annot.h"
 #include "fpdfsdk/include/fsdk_actionhandler.h"
-#include "fpdfsdk/include/fsdk_baseform.h"
 #include "fpdfsdk/include/fsdk_common.h"
 #include "fpdfsdk/include/fsdk_define.h"
 #include "public/fpdf_formfill.h"
diff --git a/fpdfsdk/include/pdfsdk_fieldaction.h b/fpdfsdk/include/pdfsdk_fieldaction.h
new file mode 100644
index 0000000..385fbf6
--- /dev/null
+++ b/fpdfsdk/include/pdfsdk_fieldaction.h
@@ -0,0 +1,39 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_INCLUDE_PDFSDK_FIELDACTION_H_
+#define FPDFSDK_INCLUDE_PDFSDK_FIELDACTION_H_
+
+#include "core/fxcrt/include/fx_string.h"
+
+#ifdef PDF_ENABLE_XFA
+typedef enum {
+  PDFSDK_XFA_Click = 0,
+  PDFSDK_XFA_Full,
+  PDFSDK_XFA_PreOpen,
+  PDFSDK_XFA_PostOpen
+} PDFSDK_XFAAActionType;
+#endif  // PDF_ENABLE_XFA
+
+struct PDFSDK_FieldAction {
+  PDFSDK_FieldAction();
+  PDFSDK_FieldAction(const PDFSDK_FieldAction& other) = delete;
+
+  FX_BOOL bModifier;
+  FX_BOOL bShift;
+  int nCommitKey;
+  CFX_WideString sChange;
+  CFX_WideString sChangeEx;
+  FX_BOOL bKeyDown;
+  int nSelEnd;
+  int nSelStart;
+  CFX_WideString sValue;
+  FX_BOOL bWillCommit;
+  FX_BOOL bFieldFull;
+  FX_BOOL bRC;
+};
+
+#endif  // FPDFSDK_INCLUDE_PDFSDK_FIELDACTION_H_
diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp
index 7ddd571..e38f61d 100644
--- a/fpdfsdk/javascript/Document.cpp
+++ b/fpdfsdk/javascript/Document.cpp
@@ -15,6 +15,8 @@
 #include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
 #include "core/fpdfdoc/include/cpdf_interform.h"
 #include "core/fpdfdoc/include/cpdf_nametree.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "fpdfsdk/javascript/Field.h"
 #include "fpdfsdk/javascript/Icon.h"
diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp
index a0fa278..3b69a5a 100644
--- a/fpdfsdk/javascript/Field.cpp
+++ b/fpdfsdk/javascript/Field.cpp
@@ -14,6 +14,8 @@
 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
 #include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
 #include "core/fpdfdoc/include/cpdf_interform.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
+#include "fpdfsdk/include/cpdfsdk_widget.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "fpdfsdk/javascript/Document.h"
 #include "fpdfsdk/javascript/Icon.h"
diff --git a/fpdfsdk/javascript/PublicMethods.cpp b/fpdfsdk/javascript/PublicMethods.cpp
index 01bcfac..1dfac93 100644
--- a/fpdfsdk/javascript/PublicMethods.cpp
+++ b/fpdfsdk/javascript/PublicMethods.cpp
@@ -11,6 +11,7 @@
 
 #include "core/fpdfdoc/include/cpdf_interform.h"
 #include "core/fxcrt/include/fx_ext.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "fpdfsdk/javascript/Field.h"
 #include "fpdfsdk/javascript/JS_Define.h"
diff --git a/fpdfsdk/javascript/app.cpp b/fpdfsdk/javascript/app.cpp
index 18415dc..97c97eb 100644
--- a/fpdfsdk/javascript/app.cpp
+++ b/fpdfsdk/javascript/app.cpp
@@ -9,6 +9,7 @@
 #include <memory>
 #include <vector>
 
+#include "fpdfsdk/include/cpdfsdk_interform.h"
 #include "fpdfsdk/include/fsdk_mgr.h"
 #include "fpdfsdk/javascript/Document.h"
 #include "fpdfsdk/javascript/JS_Define.h"
diff --git a/fpdfsdk/pdfsdk_fieldaction.cpp b/fpdfsdk/pdfsdk_fieldaction.cpp
new file mode 100644
index 0000000..1157fb1
--- /dev/null
+++ b/fpdfsdk/pdfsdk_fieldaction.cpp
@@ -0,0 +1,18 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/include/pdfsdk_fieldaction.h"
+
+PDFSDK_FieldAction::PDFSDK_FieldAction()
+    : bModifier(FALSE),
+      bShift(FALSE),
+      nCommitKey(0),
+      bKeyDown(FALSE),
+      nSelEnd(0),
+      nSelStart(0),
+      bWillCommit(FALSE),
+      bFieldFull(FALSE),
+      bRC(TRUE) {}
diff --git a/pdfium.gyp b/pdfium.gyp
index 08f9dd3..d5f870c 100644
--- a/pdfium.gyp
+++ b/pdfium.gyp
@@ -86,23 +86,29 @@
       'sources': [
         'fpdfsdk/cfx_systemhandler.cpp',
         'fpdfsdk/cfx_systemhandler.h',
+        'fpdfsdk/include/cba_annotiterator.h',
         'fpdfsdk/include/cpdfsdk_annot.h',
         'fpdfsdk/include/cpdfsdk_annothandlermgr.h',
         'fpdfsdk/include/cpdfsdk_annotiterator.h',
         'fpdfsdk/include/cpdfsdk_baannot.h',
         'fpdfsdk/include/cpdfsdk_bfannothandler.h',
         'fpdfsdk/include/cpdfsdk_datetime.h',
+        'fpdfsdk/include/cpdfsdk_interform.h',
+        'fpdfsdk/include/cpdfsdk_widget.h',
         'fpdfsdk/include/cpdfsdk_xfaannothandler.h',
         'fpdfsdk/include/fsdk_actionhandler.h',
-        'fpdfsdk/include/fsdk_baseform.h',
         'fpdfsdk/include/fsdk_pauseadapter.h',
         'fpdfsdk/include/ipdfsdk_annothandler.h',
+        'fpdfsdk/include/pdfsdk_fieldaction.h',
+        'fpdfsdk/cba_annotiterator.cpp',
         'fpdfsdk/cpdfsdk_annot.cpp',
         'fpdfsdk/cpdfsdk_annothandlermgr.cpp',
         'fpdfsdk/cpdfsdk_annotiterator.cpp',
         'fpdfsdk/cpdfsdk_baannot.cpp',
         'fpdfsdk/cpdfsdk_bfannothandler.cpp',
         'fpdfsdk/cpdfsdk_datetime.cpp',
+        'fpdfsdk/cpdfsdk_interform.cpp',
+        'fpdfsdk/cpdfsdk_widget.cpp',
         'fpdfsdk/cpdfsdk_xfaannothandler.cpp',
         'fpdfsdk/fpdfdoc.cpp',
         'fpdfsdk/fpdfeditimg.cpp',
@@ -120,9 +126,9 @@
         'fpdfsdk/fpdf_sysfontinfo.cpp',
         'fpdfsdk/fpdf_transformpage.cpp',
         'fpdfsdk/fsdk_actionhandler.cpp',
-        'fpdfsdk/fsdk_baseform.cpp',
         'fpdfsdk/fsdk_mgr.cpp',
         'fpdfsdk/fsdk_pauseadapter.cpp',
+        'fpdfsdk/pdfsdk_fieldaction.cpp',
         'public/fpdf_dataavail.h',
         'public/fpdf_doc.h',
         'public/fpdf_edit.h',
@@ -144,6 +150,10 @@
           'dependencies': [
             'fpdfxfa',
            ],
+          'sources': [
+            'fpdfsdk/cpdfsdk_xfawidget.cpp',
+            'fpdfsdk/include/cpdfsdk_xfawidget.h',
+          ],
         }],
         ['bundle_freetype==1', {
           'dependencies': [